import 'dart:async'; import 'package:didvan/config/auth_config.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/slider_data.dart'; import 'package:didvan/providers/core.dart'; import 'package:didvan/services/app_initalizer.dart'; import 'package:didvan/services/content/content_service.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; import 'package:collection/collection.dart'; class PodcastsState extends CoreProvier { final List studios = []; final List sliders = []; String? startDate; String? endDate; String search = ''; String lastSearch = ''; int page = 1; int lastPage = 1; int selectedSortTypeIndex = 0; bool _videosSelected = true; bool get videosSelected => _videosSelected; bool get searching => search.isNotEmpty; void resetFilters(bool isInit) { startDate = null; endDate = null; search = ''; lastSearch = ''; if (!isInit) { getStudios(page: 1); } } set videosSelected(bool value) { if (_videosSelected == value || appState == AppState.busy) return; _videosSelected = value; selectedSortTypeIndex = 0; _getSliders(); getStudios(page: page); } String get order { if (selectedSortTypeIndex == 0 || selectedSortTypeIndex == 1) return 'date'; if (selectedSortTypeIndex == 2) return 'view'; return 'comment'; } String get orderString { if (selectedSortTypeIndex == 0) return 'جدیدترین‌ها'; if (selectedSortTypeIndex == 1) return 'قدیمی‌ترین‌ها'; if (selectedSortTypeIndex == 2) return 'پربازدیدترین‌ها'; return 'پربحث‌ترین‌ها'; } String get type { if (videosSelected) return 'video'; return 'podcast'; } void init(bool? viewPodcasts) { search = ''; lastSearch = ''; _videosSelected = !(AppInitializer.clickAction?.contains('podcast') == true) && viewPodcasts != true; selectedSortTypeIndex = 0; Future.delayed(Duration.zero, () { _getSliders(); getStudios(page: 1); }); } Future _getSliders() async { if (!AuthConfig.useLegacyApi) { sliders.clear(); notifyListeners(); return; } final service = RequestService( RequestHelper.studioSlider(type), ); await service.httpGet(); if (service.isSuccess) { sliders.clear(); final sliderItems = service.result['studios']; for (var i = 0; i < sliderItems.length; i++) { sliders.add(SliderData.fromJson(sliderItems[i])); } } notifyListeners(); } static const String _podcastCategoryId = '7cbe250a-d0c4-44c2-970b-c4abbdf0d6c2'; static const String _videocastCategoryId = '321a1cc9-b1e0-4787-a8db-6faa9a3477c4'; static const String _visibleStatusFilter = '\$in:accepted,published'; Future getStudios({required int page}) async { this.page = page; lastSearch = search; if (page == 1) { appState = AppState.busy; } if (type == 'podcast') { await _getMediaFromContentService(page, _podcastCategoryId, isVideo: false); return; } if (type == 'video') { await _getMediaFromContentService(page, _videocastCategoryId, isVideo: true); return; } final service = RequestService( RequestHelper.studioOverviews( args: StudioRequestArgs( page: page, type: type, search: search, order: order, asc: selectedSortTypeIndex == 1, endDate: endDate?.split(' ').first, startDate: startDate?.split(' ').first, ), ), ); await service.httpGet(); if (service.isSuccess) { if (page == 1) { studios.clear(); } lastPage = service.result['lastPage']; final studioItems = service.result['studios']; for (var i = 0; i < studioItems.length; i++) { studios.add(OverviewData.fromJson(studioItems[i])); } appState = AppState.idle; return; } appState = AppState.failed; } Future _getMediaFromContentService( int page, String categoryId, { required bool isVideo, }) async { final res = await ContentService.instance.getContents( page: page, limit: 100, search: search.isEmpty ? null : search, filterStatus: _visibleStatusFilter, categoryId: categoryId, sortBy: [_mediaSort()], ); if (!res.isSuccess || res.data == null) { appState = AppState.failed; return; } final data = res.data!; if (page == 1) { studios.clear(); } final initial = data.data .map((c) => isVideo ? OverviewData.fromVideocastContent(c) : OverviewData.fromPodcastContent(c)) .toList(); studios.addAll(initial); lastPage = data.totalPages; final fetches = >[]; for (var i = 0; i < studios.length; i++) { final ov = studios[i]; if (ov.keycloakId == null) continue; if ((ov.duration != null && ov.duration! > 0) && (ov.link != null && ov.link!.isNotEmpty)) { continue; } fetches .add(ContentService.instance.getContent(ov.keycloakId!).then((res) { if (!res.isSuccess || res.data == null) return; final item = res.data!; final newOv = isVideo ? OverviewData.fromVideocastContent(item) : OverviewData.fromPodcastContent(item); final idx = studios.indexWhere((e) => e.keycloakId == ov.keycloakId); if (idx >= 0) studios[idx] = newOv; }).catchError((_) {})); } await Future.wait(fetches); appState = AppState.idle; notifyListeners(); } MapEntry _mediaSort() { switch (selectedSortTypeIndex) { case 1: return const MapEntry('createdAt', 'ASC'); case 2: return const MapEntry('readCount', 'DESC'); case 3: return const MapEntry('likeCount', 'DESC'); default: return const MapEntry('createdAt', 'DESC'); } } Future changeMark(int id, bool value, bool shouldUpdate) async { studios.firstWhereOrNull((element) => element.id == id)?.marked = value; if (shouldUpdate) { notifyListeners(); } } void onCommentsChanged(int id, int count) { studios.firstWhere((radar) => radar.id == id).comments = count; notifyListeners(); } }