import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:fladder/jellyfin/jellyfin_open_api.enums.swagger.dart'; import 'package:fladder/models/home_model.dart'; import 'package:fladder/models/item_base_model.dart'; import 'package:fladder/providers/api_provider.dart'; import 'package:fladder/providers/service_provider.dart'; import 'package:fladder/providers/settings/client_settings_provider.dart'; import 'package:fladder/providers/views_provider.dart'; import 'package:fladder/util/list_extensions.dart'; final dashboardProvider = StateNotifierProvider((ref) { return DashboardNotifier(ref); }); class DashboardNotifier extends StateNotifier { DashboardNotifier(this.ref) : super(HomeModel()); final Ref ref; late final JellyService api = ref.read(jellyApiProvider); Future fetchNextUpAndResume() async { if (state.loading) return; state = state.copyWith(loading: true); final viewTypes = ref.read(viewsProvider.select((value) => value.dashboardViews)).map((e) => e.collectionType).toSet().toList(); final limit = 16; final imagesToFetch = { ImageType.logo, ImageType.primary, ImageType.backdrop, ImageType.banner, }.toList(); final fieldsToFetch = [ ItemFields.parentid, ItemFields.mediastreams, ItemFields.mediasources, ItemFields.candelete, ItemFields.candownload, ItemFields.primaryimageaspectratio, ItemFields.overview, ItemFields.genres, ]; if (viewTypes.containsAny([CollectionType.movies, CollectionType.tvshows])) { final resumeVideoResponse = await api.usersUserIdItemsResumeGet( enableImageTypes: imagesToFetch, fields: fieldsToFetch, mediaTypes: [MediaType.video], enableTotalRecordCount: false, limit: limit, ); state = state.copyWith( resumeVideo: resumeVideoResponse.body?.items?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList(), ); } if (viewTypes.contains(CollectionType.music)) { final resumeAudioResponse = await api.usersUserIdItemsResumeGet( enableImageTypes: imagesToFetch, fields: fieldsToFetch, mediaTypes: [MediaType.audio], enableTotalRecordCount: false, limit: limit, ); state = state.copyWith( resumeAudio: resumeAudioResponse.body?.items?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList(), ); } if (viewTypes.contains(CollectionType.books)) { final resumeBookResponse = await api.usersUserIdItemsResumeGet( enableImageTypes: imagesToFetch, fields: fieldsToFetch, mediaTypes: [MediaType.book], enableTotalRecordCount: false, limit: limit, ); state = state.copyWith( resumeBooks: resumeBookResponse.body?.items?.map((e) => ItemBaseModel.fromBaseDto(e, ref)).toList(), ); } final nextResponse = await api.showsNextUpGet( nextUpDateCutoff: DateTime.now().subtract( ref.read(clientSettingsProvider.select((value) => value.nextUpDateCutoff ?? const Duration(days: 28)))), fields: fieldsToFetch, ); final next = nextResponse.body?.items ?.map( (e) => ItemBaseModel.fromBaseDto(e, ref), ) .toList() ?? []; state = state.copyWith(nextUp: next, loading: false); } void clear() { state = HomeModel(); } }