@@ -32,7 +32,7 @@ import 'package:unyo/domain/entities/media_list.dart';
3232import 'package:unyo/domain/entities/media_list_entry.dart' ;
3333import 'package:unyo/domain/entities/settings.dart' ;
3434import 'package:unyo/domain/entities/user.dart' ;
35- import 'package:unyo/presentation/dialogs/anime_server_selection_dialog .dart' ;
35+ import 'package:unyo/presentation/dialogs/anime_details_media_entry_dialog .dart' ;
3636
3737class AnimeDetailsCubit extends Cubit <AnimeDetailsState > with EffectMixin <AnimeDetailsState > {
3838 // Repositories
@@ -67,7 +67,7 @@ class AnimeDetailsCubit extends Cubit<AnimeDetailsState> with EffectMixin<AnimeD
6767 loggedUser: UserModel .empty (),
6868 selectedMediaList: MediaListModel .empty (),
6969 selectedAnime: AnimeModel .empty (),
70- mediaListEntry: MediaListEntryModel .empty (),
70+ mediaListEntry: MediaListEntryModel .empty (),
7171 characters: (false , []),
7272 recommendations: (false , []),
7373 episodesInfo: [],
@@ -133,9 +133,9 @@ class AnimeDetailsCubit extends Cubit<AnimeDetailsState> with EffectMixin<AnimeD
133133
134134 void navigateToAnimeAdvancedSearchScreenWithFilters (BuildContext context, String newAnimeGenre) {
135135 _logger.i ("Navigating to Anime Advanced Search Filters" );
136- bool hasAnimeSearchInStack = AutoRouter .of (context).stackData. any (
137- (route) => route.name == "AnimeAdvancedSearchRoute" ,
138- );
136+ bool hasAnimeSearchInStack = AutoRouter .of (
137+ context ,
138+ ).stackData. any ((route) => route.name == "AnimeAdvancedSearchRoute" ) ;
139139 if (hasAnimeSearchInStack) {
140140 _selectedAnimeAdvancedSearchGenresFilters.updateSelectedAnimeGenre (newAnimeGenre);
141141 popRouteEffect (context);
@@ -175,7 +175,108 @@ class AnimeDetailsCubit extends Cubit<AnimeDetailsState> with EffectMixin<AnimeD
175175 }
176176
177177 void openAnimeServerSelectionDialog (BuildContext context) {
178- showWidgetDialogEffect (dialog: const AnimeServerSelectionDialog ());
178+ showWidgetDialogEffect (dialog: AnimeDetailsMediaEntryDialog (cubit: this ));
179+ }
180+
181+ Future <void > updateMediaListEntry (BuildContext context) async {
182+ MediaListEntry desiredMediaListEntry = state.mediaListEntry;
183+ try {
184+ switch (state.loggedUser.settings.service) {
185+ case Service .anilist:
186+ _logger.i ("Updating Media List Entry to $desiredMediaListEntry on Anilist" );
187+ MediaListEntry savedMediaListEntry = await _animeRepositoryAnilist.updateMediaListEntry (
188+ desiredMediaListEntry,
189+ state.selectedAnime,
190+ state.loggedUser,
191+ );
192+ emit (state.copyWith (mediaListEntry: savedMediaListEntry));
193+ case Service .mal:
194+ _logger.i ("Updating Media List Entry to $desiredMediaListEntry on MyAnimeList" );
195+ case Service .shikimori:
196+ _logger.i ("Updating Media List Entry to $desiredMediaListEntry on Shikimori" );
197+ case Service .kitsu:
198+ _logger.i ("Updating Media List Entry to $desiredMediaListEntry on Kitsu" );
199+ case Service .simkl:
200+ _logger.i ("Updating Media List Entry to $desiredMediaListEntry on Simkl" );
201+ }
202+
203+ } on HttpServerException catch (e, stackTrace) {
204+ handleError ("Error updating Anime Entry:" , responseBody: e.message, stackTrace: stackTrace);
205+ } catch (e, stackTrace) {
206+ handleError ("Error updating Anime Entry: $e " , stackTrace: stackTrace);
207+ }
208+ if (! context.mounted) return ;
209+ popRouteEffect (context);
210+ }
211+
212+ Future <void > updateMediaListEntryStatus (String ? newStatus) async {
213+ if (newStatus == null ) return ;
214+ try {
215+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (status: newStatus);
216+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
217+ } catch (e, stackTrace) {
218+ handleError ("Error updating Anime Entry status: $e " , stackTrace: stackTrace);
219+ }
220+ }
221+
222+ Future <void > updateMediaListEntryProgress (int ? newProgress) async {
223+ if (newProgress == null ) return ;
224+ try {
225+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (progress: newProgress);
226+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
227+ } catch (e, stackTrace) {
228+ handleError ("Error updating Anime Entry progress: $e " , stackTrace: stackTrace);
229+ }
230+ }
231+
232+ Future <void > updateMediaListEntryScore (double ? newScore) async {
233+ if (newScore == null ) return ;
234+ try {
235+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (score: newScore);
236+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
237+ } catch (e, stackTrace) {
238+ handleError ("Error updating Anime Entry score: $e " , stackTrace: stackTrace);
239+ }
240+ }
241+
242+ Future <void > updateMediaListEntryRepeat (int ? newRepeat) async {
243+ if (newRepeat == null ) return ;
244+ try {
245+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (repeat: newRepeat);
246+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
247+ } catch (e, stackTrace) {
248+ handleError ("Error updating Anime Entry repeat: $e " , stackTrace: stackTrace);
249+ }
250+ }
251+
252+ Future <void > updateMediaListEntryStartedAt (BuildContext context) async {
253+ DateTime ? selectedDateTime = await showDatePicker (
254+ context: context,
255+ firstDate: DateTime .now ().subtract (const Duration (days: 365 )),
256+ lastDate: DateTime .now ().add (const Duration (days: 365 )),
257+ );
258+ if (selectedDateTime == null ) return ;
259+ try {
260+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (startedAt: [selectedDateTime.day.toString (), selectedDateTime.month.toString (), selectedDateTime.year.toString ()]);
261+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
262+ } catch (e, stackTrace) {
263+ handleError ("Error updating Anime Entry started at: $e " , stackTrace: stackTrace);
264+ }
265+ }
266+
267+ Future <void > updateMediaListEntryCompletedAt (BuildContext context) async {
268+ DateTime ? selectedDateTime = await showDatePicker (
269+ context: context,
270+ firstDate: DateTime .now ().subtract (const Duration (days: 365 )),
271+ lastDate: DateTime .now ().add (const Duration (days: 365 )),
272+ );
273+ if (selectedDateTime == null ) return ;
274+ try {
275+ MediaListEntry updatedMediaListEntry = (state.mediaListEntry as MediaListEntryModel ).copyWith (completedAt: [selectedDateTime.day.toString (), selectedDateTime.month.toString (), selectedDateTime.year.toString ()]);
276+ emit (state.copyWith (mediaListEntry: updatedMediaListEntry));
277+ } catch (e, stackTrace) {
278+ handleError ("Error updating Anime Entry completed at: $e " , stackTrace: stackTrace);
279+ }
179280 }
180281
181282 Future <void > _getAnimeDetails (User loggedUser, Anime selectedAnime) async {
@@ -198,7 +299,10 @@ class AnimeDetailsCubit extends Cubit<AnimeDetailsState> with EffectMixin<AnimeD
198299 ),
199300 );
200301 if (animeDetails.$2.recommendedAnimes.isEmpty) {
201- (bool , List <Anime >) trendingAnimes = await _animeRepositoryAnilist.getTrendingAnimes (1 , loggedUser);
302+ (bool , List <Anime >) trendingAnimes = await _animeRepositoryAnilist.getTrendingAnimes (
303+ 1 ,
304+ loggedUser,
305+ );
202306 emit (state.copyWith (recommendations: (trendingAnimes.$1, trendingAnimes.$2.shuffled (Random ()))));
203307 }
204308 _getAlternativeImage (loggedUser, selectedAnime);
0 commit comments