Fladder/lib/providers/dashboard_provider.dart
2025-10-11 18:46:25 +02:00

105 lines
3.3 KiB
Dart

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<DashboardNotifier, HomeModel>((ref) {
return DashboardNotifier(ref);
});
class DashboardNotifier extends StateNotifier<HomeModel> {
DashboardNotifier(this.ref) : super(HomeModel());
final Ref ref;
late final JellyService api = ref.read(jellyApiProvider);
Future<void> 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 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,
);
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,
);
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,
);
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();
}
}