forked from eatvio/eatvio_app
230 lines
8.6 KiB
Dart
230 lines
8.6 KiB
Dart
import 'dart:async';
|
|
import 'dart:developer';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:easy_debounce/easy_debounce.dart';
|
|
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
|
import 'package:eatvio_app/core/utils/toasts.dart';
|
|
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
|
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_state.dart';
|
|
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
|
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
class AboutDietCubit extends Cubit<AboutDietState> {
|
|
AboutDietCubit({required this.dietsRepository, required this.profileRepository}) : super(const AboutDietState.initial());
|
|
final DietRepository dietsRepository;
|
|
final ProfileRepository profileRepository;
|
|
bool isCurrentDietStarted = false;
|
|
bool hasStartedDiet = false;
|
|
String? userStartedDietName;
|
|
List<int> _selectedIndexes = [];
|
|
|
|
Future<void> getDiet(String slug, {int? index}) async {
|
|
try {
|
|
final diet = await dietsRepository.getDietBySlug(slug);
|
|
if (index != null) {
|
|
dietsRepository.emitCommentsStateToFeed(CommentsState(index: index, totalComments: diet.totalComments));
|
|
}
|
|
emit(AboutDietState.loaded(diet: diet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
} catch (e) {
|
|
log(e.toString());
|
|
emit(AboutDietState.error(message: e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> initDietPage(String slug) async {
|
|
try {
|
|
emit(const AboutDietState.loading());
|
|
final diet = await dietsRepository.getDietBySlug(slug);
|
|
final chosenDiets = await profileRepository.getChosenDiets();
|
|
final lastChosenDiet = chosenDiets.firstOrNull;
|
|
if (lastChosenDiet != null && ['inited', 'started'].contains(lastChosenDiet.state)) {
|
|
hasStartedDiet = true;
|
|
if (diet.id == lastChosenDiet.dietId) {
|
|
isCurrentDietStarted = true;
|
|
} else {
|
|
if (lastChosenDiet.dietId != null) {
|
|
final chosenDiet = await dietsRepository.getDiet(lastChosenDiet.dietId!);
|
|
userStartedDietName = chosenDiet.name;
|
|
}
|
|
}
|
|
}
|
|
_selectedIndexes = List.generate(diet.dailySchedule.length, (index) => 0);
|
|
emit(AboutDietState.loaded(
|
|
diet: diet,
|
|
isStarted: isCurrentDietStarted,
|
|
hasStartedDiet: hasStartedDiet,
|
|
selectedIndexes: _selectedIndexes,
|
|
));
|
|
} catch (e) {
|
|
log(e.toString());
|
|
emit(AboutDietState.error(message: e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> likeDiet(int id, int? dietIndexInFeed) async {
|
|
if (state is! DietStateLoaded) return;
|
|
|
|
final currentDiet = (state as DietStateLoaded).diet;
|
|
|
|
if (currentDiet.wasLikedByMe) {
|
|
final updatedDiet = currentDiet.copyWith(
|
|
totalLikes: currentDiet.totalLikes - 1,
|
|
wasLikedByMe: false,
|
|
);
|
|
if (dietIndexInFeed != null) {
|
|
dietsRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: updatedDiet.wasLikedByMe, totalLikes: updatedDiet.totalLikes, index: dietIndexInFeed));
|
|
}
|
|
emit(AboutDietState.loaded(diet: updatedDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet, selectedIndexes: _selectedIndexes));
|
|
} else {
|
|
final updatedDiet = currentDiet.copyWith(
|
|
totalLikes: currentDiet.totalLikes + 1,
|
|
wasLikedByMe: true,
|
|
);
|
|
if (dietIndexInFeed != null) {
|
|
dietsRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: updatedDiet.wasLikedByMe, totalLikes: updatedDiet.totalLikes, index: dietIndexInFeed));
|
|
}
|
|
emit(AboutDietState.loaded(diet: updatedDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet, selectedIndexes: _selectedIndexes));
|
|
}
|
|
|
|
EasyDebounce.debounce(
|
|
'like_diet',
|
|
const Duration(seconds: 1),
|
|
() async {
|
|
try {
|
|
await dietsRepository.likeDiet(id);
|
|
} catch (e) {
|
|
log(e.toString());
|
|
if (dietIndexInFeed != null) {
|
|
dietsRepository
|
|
.emitLikesStateToFeed(LikesState(wasLikedByMe: currentDiet.wasLikedByMe, totalLikes: currentDiet.totalLikes, index: dietIndexInFeed));
|
|
}
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: currentDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> addToFavorite(int id, int? dietIndex) async {
|
|
if (state is! DietStateLoaded) return;
|
|
|
|
final currentDiet = (state as DietStateLoaded).diet;
|
|
|
|
final updatedDiet = currentDiet.copyWith(
|
|
isFavorite: true,
|
|
);
|
|
if (dietIndex != null) {
|
|
dietsRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: updatedDiet.isFavorite, index: dietIndex));
|
|
}
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: updatedDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
|
|
EasyDebounce.debounce(
|
|
'add_or_remove_diet_to_favorites',
|
|
const Duration(seconds: 1),
|
|
() async {
|
|
try {
|
|
await dietsRepository.addToFavorite(id);
|
|
} catch (e) {
|
|
log(e.toString());
|
|
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
|
if (dietIndex != null) {
|
|
dietsRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndex));
|
|
}
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: currentDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> removeFromFavorite(int id, int? dietIndex) async {
|
|
if (state is! DietStateLoaded) return;
|
|
|
|
final currentDiet = (state as DietStateLoaded).diet;
|
|
|
|
final updatedDiet = currentDiet.copyWith(
|
|
isFavorite: false,
|
|
);
|
|
if (dietIndex != null) {
|
|
dietsRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: updatedDiet.isFavorite, index: dietIndex));
|
|
}
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: updatedDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
|
|
EasyDebounce.debounce(
|
|
'add_or_remove_diet_to_favorites',
|
|
const Duration(seconds: 1),
|
|
() async {
|
|
try {
|
|
await dietsRepository.removeFromFavorite(id);
|
|
} catch (e) {
|
|
log(e.toString());
|
|
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
|
if (dietIndex != null) {
|
|
dietsRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: currentDiet.isFavorite, index: dietIndex));
|
|
}
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: currentDiet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<bool> startDiet(DateTime date) async {
|
|
try {
|
|
if (state is! DietStateLoaded) return false;
|
|
|
|
final id = (state as DietStateLoaded).diet.id;
|
|
final stringDate = date.format('yyyy-MM-dd');
|
|
await dietsRepository.startDiet(id, stringDate);
|
|
return true;
|
|
} catch (e, st) {
|
|
log(e.toString(), stackTrace: st);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> cancelDiet() async {
|
|
try {
|
|
if (state is! DietStateLoaded) return false;
|
|
final id = (state as DietStateLoaded).diet.id;
|
|
await dietsRepository.cancelDiet(id);
|
|
return true;
|
|
} on DioException catch (e) {
|
|
log(e.toString());
|
|
return false;
|
|
} catch (e) {
|
|
log(e.toString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void clearStartedDietsState() {
|
|
if (state is! DietStateLoaded) return;
|
|
final diet = (state as DietStateLoaded).diet;
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: diet));
|
|
}
|
|
|
|
void emitCurrentStartedDietsState() {
|
|
if (state is! DietStateLoaded) return;
|
|
final diet = (state as DietStateLoaded).diet;
|
|
emit(AboutDietState.loaded(selectedIndexes: _selectedIndexes,diet: diet, isStarted: true));
|
|
}
|
|
|
|
Future<Diet?> getDietBySlug(String slug) async {
|
|
try {
|
|
return await dietsRepository.getDietBySlug(slug);
|
|
} catch (e) {
|
|
log(e.toString());
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void setSelectedIndex({required int dayNumber, required int index}) {
|
|
final currentState = state;
|
|
if (currentState is DietStateLoaded) {
|
|
final updatedSelectedIndexes = [...currentState.selectedIndexes];
|
|
updatedSelectedIndexes[dayNumber] = index;
|
|
_selectedIndexes = updatedSelectedIndexes;
|
|
emit(currentState.copyWith(selectedIndexes: _selectedIndexes));
|
|
}
|
|
}
|
|
}
|