import 'dart:async'; import 'dart:ui'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:tunas/repositories/metadata/metadata_repository.dart'; import 'package:tunas/repositories/metadata/models/category.dart'; import 'package:tunas/repositories/transactions/models/transaction.dart'; import 'package:tunas/repositories/transactions/transactions_repository.dart'; import 'package:uuid/uuid.dart'; part 'category_event.dart'; part 'category_state.dart'; class CategoryBloc extends Bloc { final MetadataRepository _metadataRepository; final TransactionsRepository _transactionsRepository; CategoryBloc({ required MetadataRepository metadataRepository, required TransactionsRepository transactionsRepository, }) : _metadataRepository = metadataRepository, _transactionsRepository = transactionsRepository, super(const CategoryState()) { on(_onCategoriesLoad); on(_onCategoryEditColor); on(_onCategoryEditTransfert); on(_onCategoryEditEssential); on(_onCategoryEditLabel); on(_onCategoryRemove); on(_onCategoryAdd); _metadataRepository .getCategoriesStream() .listen((categories) => add(CategoriesLoad(categories))); } _onCategoriesLoad( CategoriesLoad event, Emitter emit ) { emit(_computeState(event.categories)); } FutureOr _onCategoryEditColor(CategoryEditColor event, Emitter emit) { Category category = event.category; category.color = event.color; emit(_computeState(_saveCategory(category))); } FutureOr _onCategoryEditTransfert(CategoryEditTransfert event, Emitter emit) { Category category = event.category; category.transfert = event.transfert; emit(_computeState(_saveCategory(category))); } FutureOr _onCategoryEditEssential(CategoryEditEssential event, Emitter emit) { Category category = event.category; category.essential = event.essential; emit(_computeState(_saveCategory(category))); } FutureOr _onCategoryEditLabel(CategoryEditLabel event, Emitter emit) { // TODO check for existance, rename every transaction } FutureOr _onCategoryRemove(CategoryRemove event, Emitter emit) { CategoryState originalCategoryState = state.copyWith(); Category categoryToRemove = event.category; List categories = state.categories; List transactions = _transactionsRepository.getTransactions(); if (transactions.any((transaction) => transaction.category == categoryToRemove.label)) { emit(CategoryRemoveFail()); emit(originalCategoryState); } else { categories.removeWhere((category) => category.label == categoryToRemove.label); emit(CategoryRemoveSucess()); emit(_computeState(_metadataRepository.saveCategories(categories))); } } FutureOr _onCategoryAdd(CategoryAdd event, Emitter emit) { String uuid = const Uuid().v8(); Category category = Category( label: 'Category $uuid', color: 'FF74feff', ); emit(_computeState(_saveCategory(category))); } List _saveCategory(Category categoryToSave) { List categories = _metadataRepository.getCategories(); try { Category categoryFound = categories.firstWhere((category) => category.label == categoryToSave.label); categoryFound.color = categoryToSave.color; categoryFound.essential = categoryToSave.essential; categoryFound.transfert = categoryToSave.transfert; } catch (e) { if (categories.isEmpty) { categories = [categoryToSave]; } else { categories.add(categoryToSave); } } _metadataRepository.saveCategories(categories); return categories; } CategoryState _computeState(List categories) { return state.copyWith( categories: categories, categoriesColors: { for (var category in categories) category.label : category.rgbToColor() } ); } }