import 'package:chopper/chopper.dart'; import 'package:collection/collection.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:fladder/models/item_base_model.dart'; import 'package:fladder/models/items/episode_model.dart'; import 'package:fladder/models/items/item_shared_models.dart'; import 'package:fladder/models/items/series_model.dart'; import 'package:fladder/providers/api_provider.dart'; import 'package:fladder/providers/service_provider.dart'; import 'package:fladder/providers/sync_provider.dart'; class EpisodeDetailModel { final SeriesModel? series; final List episodes; final EpisodeModel? episode; final List guestActors; EpisodeDetailModel({ this.series, this.episodes = const [], this.episode, this.guestActors = const [], }); EpisodeDetailModel copyWith({ SeriesModel? series, List? episodes, EpisodeModel? episode, List? guestActors, }) { return EpisodeDetailModel( series: series ?? this.series, episodes: episodes ?? this.episodes, episode: episode ?? this.episode, guestActors: guestActors ?? this.guestActors, ); } } final episodeDetailsProvider = StateNotifierProvider.autoDispose.family((ref, id) { return EpisodeDetailsProvider(ref); }); class EpisodeDetailsProvider extends StateNotifier { EpisodeDetailsProvider(this.ref) : super(EpisodeDetailModel()); final Ref ref; late final JellyService api = ref.read(jellyApiProvider); Future fetchDetails(ItemBaseModel item) async { try { final seriesResponse = await api.usersUserIdItemsItemIdGet(itemId: item.parentBaseModel.id); if (seriesResponse.body == null) return null; final episodes = await api.showsSeriesIdEpisodesGet(seriesId: item.parentBaseModel.id); if (episodes.body == null) return null; final episode = (await api.usersUserIdItemsItemIdGet(itemId: item.id)).bodyOrThrow as EpisodeModel; state = state.copyWith( series: seriesResponse.bodyOrThrow as SeriesModel, episodes: EpisodeModel.episodesFromDto(episodes.bodyOrThrow.items, ref), episode: episode, ); return seriesResponse; } catch (e) { _tryToCreateOfflineState(item); return null; } } Future _tryToCreateOfflineState(ItemBaseModel item) async { final syncNotifier = ref.read(syncProvider.notifier); final episodeModel = (await syncNotifier.getSyncedItem(item.id))?.itemModel as EpisodeModel?; if (episodeModel == null) return; final seriesSyncedItem = await syncNotifier.getSyncedItem(episodeModel.parentBaseModel.id); if (seriesSyncedItem == null) return; final seriesModel = seriesSyncedItem.itemModel as SeriesModel?; if (seriesModel == null) return; final episodes = (await syncNotifier.getNestedChildren(seriesSyncedItem)) .map((e) => e.itemModel) .whereType() .toList(); state = state.copyWith( series: seriesModel, episode: episodes.firstWhereOrNull((element) => element.id == item.id), episodes: episodes, ); return; } void setSubIndex(int index) { state = state.copyWith( episode: state.episode?.copyWith( mediaStreams: state.episode?.mediaStreams.copyWith( defaultSubStreamIndex: index, ))); } void setAudioIndex(int index) { state = state.copyWith( episode: state.episode?.copyWith( mediaStreams: state.episode?.mediaStreams.copyWith( defaultAudioStreamIndex: index, ))); } void setVersionIndex(int index) { state = state.copyWith( episode: state.episode?.copyWith( mediaStreams: state.episode?.mediaStreams.copyWith( versionStreamIndex: index, ))); } }