Files
eatvio_app/lib/features/recipes/presentation/bloc/recipe_create_cubit.dart
2024-11-12 19:05:30 +07:00

301 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/features/recipes/models/ingredient.dart';
import 'package:eatvio_app/features/recipes/models/recipe_model.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/recipe_create_state.dart';
import 'package:eatvio_app/features/recipes/reporitories/recipe_repository.dart';
import 'package:eatvio_app/features/recipes/models/product.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
class RecipeCreateCubit extends Cubit<RecipeCreateState> {
final RecipeRepository recipeRepository;
RecipeCreateCubit({required this.recipeRepository}) : super(const RecipeCreateState.loading());
loadRecipeById(String recipeID) async {
emit(const RecipeCreateStateLoading());
try {
final RecipeModel recipe = await recipeRepository.getRecipe(recipeID);
final List<SelectionPopupModel> types = [
SelectionPopupModel(title: 'Первые блюда', value: 'first_meals'),
SelectionPopupModel(title: 'Вторые блюда', value: 'second_meals'),
SelectionPopupModel(title: 'Cалаты', value: 'salads'),
SelectionPopupModel(title: 'Перекусы/закуски', value: 'snacks'),
SelectionPopupModel(title: 'Сладости', value: 'sweets'),
SelectionPopupModel(title: 'Напитки', value: 'drinks'),
SelectionPopupModel(title: 'Прочее', value: 'other'),
];
final List<SelectionPopupModel> cookingTimes = [
SelectionPopupModel(title: '10 минут', value: 10),
SelectionPopupModel(title: '20 минут', value: 20),
SelectionPopupModel(title: '30 минут', value: 30),
SelectionPopupModel(title: '1 час', value: 60),
SelectionPopupModel(title: '2 часа', value: 120),
SelectionPopupModel(title: '10 дней', value: 14400),
];
final List<SelectionPopupModel> statuses = [
SelectionPopupModel(title: 'Активна', value: 'active'),
SelectionPopupModel(title: 'Неактивна', value: 'inactive'),
];
final selectedType = types.firstWhere(
(type) => type.value == recipe.type,
orElse: () => types[0],
);
final selectedCookingTime = cookingTimes.firstWhere(
(time) => time.value == recipe.cooking_time,
orElse: () => cookingTimes[0],
);
final selectedStatus = statuses.firstWhere(
(status) => status.value == recipe.state,
orElse: () => statuses[0],
);
final stepControllers = recipe.steps?.map((step) {
return TextEditingController(text: step?.description);
}).toList();
final stepImages = recipe.steps?.map((step) {
return step?.image != null ? XFile(step!.image!) : null;
}).toList();
final ingredients = recipe.ingredients?.map((ingredient) {
return Ingredient(
name: ingredient!.name,
portion: ingredient.portion,
unit: ingredient.unit,
);
}).toList();
emit(RecipeCreateState.loaded(
picker: ImagePicker(),
recipeImage: XFile(recipe.image!),
titleController: TextEditingController(text: recipe.title),
productNameController: TextEditingController(),
ingredientController: TextEditingController(),
stepDescriptionController: TextEditingController(text: recipe.description),
youtubeLinkController: TextEditingController(text: recipe.video_url),
stepControllers: stepControllers ?? [],
stepImages: stepImages ?? [],
autocompleteList: [],
ingredients: ingredients ?? [],
numberOfSteps: 1,
ingredientAsItems: false,
types: types,
cookingTimes: cookingTimes,
statuses: statuses,
selectedType: selectedType,
selectedCookingTime: selectedCookingTime,
selectedStatus: selectedStatus,),);
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
loadRecipeCreate() {
emit(const RecipeCreateStateLoading());
try {
final List<SelectionPopupModel> types = [
SelectionPopupModel(title: 'Первые блюда', value: 'first_meals'),
SelectionPopupModel(title: 'Вторые блюда', value: 'second_meals'),
SelectionPopupModel(title: 'Cалаты', value: 'salads'),
SelectionPopupModel(title: 'Перекусы/закуски', value: 'snacks'),
SelectionPopupModel(title: 'Сладости', value: 'sweets'),
SelectionPopupModel(title: 'Напитки', value: 'drinks'),
SelectionPopupModel(title: 'Прочее', value: 'other'),
];
final List<SelectionPopupModel> cookingTimes = [
SelectionPopupModel(title: '10 минут', value: 10),
SelectionPopupModel(title: '20 минут', value: 20),
SelectionPopupModel(title: '30 минут', value: 30),
SelectionPopupModel(title: '1 час', value: 60),
SelectionPopupModel(title: '2 часа', value: 120),
SelectionPopupModel(title: '10 дней', value: 14400),
];
final List<SelectionPopupModel> statuses = [
SelectionPopupModel(title: 'Активна', value: 'active'),
SelectionPopupModel(title: 'Неактивна', value: 'inactive'),
];
emit(RecipeCreateState.loaded(
picker: ImagePicker(),
titleController: TextEditingController(),
productNameController: TextEditingController(),
ingredientController: TextEditingController(),
stepDescriptionController: TextEditingController(),
youtubeLinkController: TextEditingController(),
stepControllers: [TextEditingController()],
stepImages: [null],
autocompleteList: [],
ingredients: [],
numberOfSteps: 1,
ingredientAsItems: false,
types: types,
cookingTimes: cookingTimes,
statuses: statuses,
selectedType: types[0],
selectedCookingTime: cookingTimes[0],
selectedStatus: statuses[0],),);
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
publishRecipe(RecipeModel recipe) async {
await recipeRepository.publishRecipe(recipe);
}
editRecipe(RecipeModel recipe, String id) async {
await recipeRepository.editRecipe(recipe, id);
}
uploadRecipeImage(XFile? pickedFile) {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
var updatedState = currentState.copyWith(
recipeImage: pickedFile,
);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
uploadStepImage(XFile? pickedFile, int stepNumber) {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
var updatedStepImages = List<XFile?>.from(currentState.stepImages);
if (stepNumber >= 0 && stepNumber < updatedStepImages.length) {
updatedStepImages[stepNumber] = pickedFile;
}
var updatedState = currentState.copyWith(
stepImages: updatedStepImages,
);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
switchUnits(bool value) {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
var updatedState = currentState.copyWith(ingredientAsItems: value);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
addIngredient(Ingredient ingredient) {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
bool ingredientExists = currentState.ingredients.any((existingIngredient) => existingIngredient.name == ingredient.name);
if (ingredientExists) {
emit(RecipeCreateState.error(errorMessage: 'Ингредиент уже существует.'));
return;
}
List<Ingredient> newIngredients = List<Ingredient>.from(currentState.ingredients);
newIngredients.add(ingredient);
var updatedState = currentState.copyWith(ingredients: newIngredients);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
addStep() {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
List<XFile?> newStepImages = List<XFile?>.from(currentState.stepImages);
newStepImages.add(null);
List<TextEditingController> newStepControllers = List<TextEditingController>.from(currentState.stepControllers);
newStepControllers.add(TextEditingController());
var updatedState = currentState.copyWith(stepImages: newStepImages, stepControllers: newStepControllers, numberOfSteps: currentState.numberOfSteps + 1);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
removeStep() {
try {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
List<XFile?> newStepImages = List<XFile?>.from(currentState.stepImages);
newStepImages.removeLast();
List<TextEditingController> newStepControllers = List<TextEditingController>.from(currentState.stepControllers);
newStepControllers.removeLast();
var updatedState = currentState.copyWith(stepImages: newStepImages, stepControllers: newStepControllers, numberOfSteps: currentState.numberOfSteps - 1);
emit(updatedState);
}
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
}
inputProduct(String input) async {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
final Map<String, List<Product>> productNutritionalValues = await recipeRepository.inputProduct(input);
var updatedState = currentState.copyWith(
productNameController: TextEditingController(text: input),
autocompleteList: productNutritionalValues['product_nutritional_value'] ?? [],
);
emit(updatedState);
}
}
changeType(SelectionPopupModel type) {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
RecipeCreateStateLoaded updatedState = currentState.copyWith(
selectedType: type,
);
emit(updatedState);
}
}
changeStatus(SelectionPopupModel status) {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
RecipeCreateStateLoaded updatedState = currentState.copyWith(
selectedStatus: status,
);
emit(updatedState);
}
}
changeCookingTime(SelectionPopupModel cookingTime) {
if (state is RecipeCreateStateLoaded) {
var currentState = state as RecipeCreateStateLoaded;
RecipeCreateStateLoaded updatedState = currentState.copyWith(
selectedCookingTime: cookingTime,
);
emit(updatedState);
}
}
}