import 'package:anitrack/src/data/anime.dart'; import 'package:anitrack/src/data/manga.dart'; import 'package:anitrack/src/data/type.dart'; import 'package:anitrack/src/service/database.dart'; import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:get_it/get_it.dart'; part 'anime_list_state.dart'; part 'anime_list_event.dart'; part 'anime_list_bloc.freezed.dart'; class AnimeListBloc extends Bloc { AnimeListBloc() : super(AnimeListState()) { on(_onAnimeAdded); on(_onMangaAdded); on(_onAnimeIncremented); on(_onAnimeDecremented); on(_onAnimesLoaded); on(_onAnimesFiltered); on(_onTrackingTypeChanged); on(_onMangasFiltered); on(_onMangaIncremented); on(_onMangaDecremented); on(_onAnimeUpdated); on(_onMangaUpdated); on(_onAnimeRemoved); on(_onMangaRemoved); } Future _onAnimeAdded(AnimeAddedEvent event, Emitter emit) async { // Add the anime to the database await GetIt.I.get().addAnime(event.data); emit( state.copyWith( animes: List.from([ ...state.animes, event.data, ]), ), ); } Future _onMangaAdded(MangaAddedEvent event, Emitter emit) async { // Add the manga to the database await GetIt.I.get().addManga(event.data); emit( state.copyWith( mangas: List.from([ ...state.mangas, event.data, ]), ), ); } Future _onAnimeIncremented(AnimeEpisodeIncrementedEvent event, Emitter emit) async { final index = state.animes.indexWhere((item) => item.id == event.id); if (index == -1) return; final anime = state.animes[index]; if (anime.episodesTotal != null && anime.episodesWatched + 1 > anime.episodesTotal!) return; final newList = List.from(state.animes); final newAnime = anime.copyWith( episodesWatched: anime.episodesWatched + 1, ); newList[index] = newAnime; emit( state.copyWith( animes: newList, ), ); await GetIt.I.get().updateAnime(newAnime); } Future _onAnimeDecremented(AnimeEpisodeDecrementedEvent event, Emitter emit) async { final index = state.animes.indexWhere((item) => item.id == event.id); if (index == -1) return; final anime = state.animes[index]; if (anime.episodesWatched - 1 < 0) return; final newList = List.from(state.animes); final newAnime = anime.copyWith( episodesWatched: anime.episodesWatched - 1, ); newList[index] = newAnime; emit( state.copyWith( animes: newList, ), ); await GetIt.I.get().updateAnime(newAnime); } Future _onAnimesLoaded(AnimesLoadedEvent event, Emitter emit) async { emit( state.copyWith( animes: await GetIt.I.get().loadAnimes(), mangas: await GetIt.I.get().loadMangas(), ), ); } Future _onAnimesFiltered(AnimeFilterChangedEvent event, Emitter emit) async { emit( state.copyWith( animeFilterState: event.filterState, ), ); } Future _onMangasFiltered(MangaFilterChangedEvent event, Emitter emit) async { emit( state.copyWith( mangaFilterState: event.filterState, ), ); } Future _onTrackingTypeChanged(AnimeTrackingTypeChanged event, Emitter emit) async { emit( state.copyWith( trackingType: event.type, ), ); } Future _onMangaIncremented(MangaChapterIncrementedEvent event, Emitter emit) async { final index = state.mangas.indexWhere((item) => item.id == event.id); if (index == -1) return; final manga = state.mangas[index]; if (manga.chaptersTotal != null && manga.chaptersRead + 1 > manga.chaptersTotal!) return; final newList = List.from(state.mangas); final newManga = manga.copyWith( chaptersRead: manga.chaptersRead + 1, ); newList[index] = newManga; emit( state.copyWith( mangas: newList, ), ); await GetIt.I.get().updateManga(newManga); } Future _onMangaDecremented(MangaChapterDecrementedEvent event, Emitter emit) async { final index = state.mangas.indexWhere((item) => item.id == event.id); if (index == -1) return; final manga = state.mangas[index]; if (manga.chaptersRead - 1 < 0) return; final newList = List.from(state.mangas); final newManga = manga.copyWith( chaptersRead: manga.chaptersRead - 1, ); newList[index] = newManga; emit( state.copyWith( mangas: newList, ), ); await GetIt.I.get().updateManga(newManga); } Future _onAnimeUpdated(AnimeUpdatedEvent event, Emitter emit) async { emit( state.copyWith( animes: List.from( state.animes.map((anime) { if (anime.id == event.anime.id) { return event.anime; } return anime; }), ), ), ); } Future _onMangaUpdated(MangaUpdatedEvent event, Emitter emit) async { emit( state.copyWith( mangas: List.from( state.mangas.map((manga) { if (manga.id == event.manga.id) { return event.manga; } return manga; }), ), ), ); } Future _onAnimeRemoved(AnimeRemovedEvent event, Emitter emit) async { emit( state.copyWith( animes: List.from( state.animes.where((anime) => anime.id != event.id), ), ), ); // Update the database await GetIt.I.get().deleteAnime(event.id); } Future _onMangaRemoved(MangaRemovedEvent event, Emitter emit) async { emit( state.copyWith( mangas: List.from( state.mangas.where((manga) => manga.id != event.id), ), ), ); // Update the database await GetIt.I.get().deleteManga(event.id); } }