import 'package:didvan/config/auth_config.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/category.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/requests/radar.dart'; import 'package:didvan/providers/core.dart'; import 'package:didvan/services/content/content_service.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; class RadarState extends CoreProvier { String search = ''; String lastSearch = ''; String? startDate; String? endDate; int page = 1; int lastPage = 1; int visibleCount = 4; bool isScrolled = false; bool shouldColapse = false; final List selectedCats = []; List categories = []; final List radars = []; bool get filtering => selectedCats.length > 1 || startDate != null || endDate != null; bool get searching => search.isNotEmpty; bool get isColapsed => (selectedCats.length == 1 && !filtering && isScrolled) || isScrolled; bool get isCategorySelected => selectedCats.length == 1 && !filtering; void resetFilters(bool isInit) { startDate = null; endDate = null; selectedCats.clear(); search = ''; lastSearch = ''; isScrolled = false; visibleCount = 4; if (!isInit) { getRadars(page: 1); } } void loadMore() { visibleCount += 4; if (visibleCount >= radars.length && page < lastPage) { getRadars(page: page + 1); } notifyListeners(); } /// شناسه‌ی دسته‌ی «پویش افق» در content-service جدید. static const String _radarCategoryId = 'f97fbe3f-5712-4e27-81d4-b309cf58e91c'; static const String _visibleStatusFilter = '\$in:accepted,published'; /// نگاشتِ CategoryData.id (1..6) به کلیدِ انگلیسیِ `metadata.category` /// که در content-service ذخیره می‌شود. String _metaKeyForCatId(CategoryData c) { switch (c.id) { case 1: return 'economical'; case 2: return 'political'; case 3: return 'technology'; case 4: return 'business'; case 5: return 'environmental'; case 6: return 'social'; default: return c.label.toLowerCase(); } } Future getRadars({ required int page, }) async { this.page = page; lastSearch = search; if (page == 1) { radars.clear(); appState = AppState.busy; } // مسیر جدید: از content-service با دسته‌ی «پویش افق». if (!AuthConfig.useLegacyApi) { // برای فیلتر کلاینت‌سایدِ زیر-دسته، limit را بزرگ‌تر می‌گیریم. final res = await ContentService.instance.getContents( page: page, limit: selectedCats.isEmpty ? 15 : 100, search: search.isEmpty ? null : search, filterStatus: _visibleStatusFilter, categoryId: _radarCategoryId, sortBy: const [MapEntry('createdAt', 'DESC')], ); if (res.isSuccess && res.data != null) { lastPage = res.data!.totalPages; // فیلتر زیر-دسته (client-side): // - metadata.category (legacy، تک‌ارزشی) // - metadata.categories (multi-select از پنل، آرایه) final selectedKeys = selectedCats.map(_metaKeyForCatId).toSet(); final filtered = selectedKeys.isEmpty ? res.data!.data : res.data!.data.where((c) { final mc = c.metaCategory?.toLowerCase(); if (mc != null && selectedKeys.contains(mc)) return true; for (final cat in c.metaCategories) { if (selectedKeys.contains(cat.toLowerCase())) return true; } return false; }).toList(); radars.addAll(filtered.map(OverviewData.fromContentItem)); if ((searching || filtering || isColapsed || isCategorySelected) && page == 1) { shouldColapse = true; } appState = AppState.idle; } else { appState = AppState.failed; } return; } final RequestService service = RequestService( RequestHelper.radarOverviews( args: RadarRequestArgs( page: page, startDate: startDate?.split(' ').first, endDate: endDate?.split(' ').first, search: search == '' ? null : search, categories: selectedCats.map((e) => e.id).toList(), ), ), ); await service.httpGet(); if (service.isSuccess) { lastPage = service.result['lastPage']; final radarsList = service.result['radars']; for (var i = 0; i < radarsList.length; i++) { radars.add(OverviewData.fromJson(radarsList[i])); } if ((searching || filtering || isColapsed || isCategorySelected) && page == 1) { shouldColapse = true; } appState = AppState.idle; return; } appState = AppState.failed; } Future changeMark(int id, bool value, bool shouldUpdate) async { radars.firstWhere((element) => element.id == id).marked = value; if (shouldUpdate) { notifyListeners(); } } Future changeLike(int id, bool value, bool shouldUpdate) async { radars.firstWhere((element) => element.id == id).liked = value; if (shouldUpdate) { notifyListeners(); } } void onCommentsChanged(int id, int count) { radars.firstWhere((radar) => radar.id == id).comments = count; notifyListeners(); } void init() { resetFilters(true); Future.delayed(Duration.zero, () { getRadars(page: 1); }); categories = [ CategoryData( id: 1, label: 'اقتصادی', asset: Assets.economicCategoryIcon, ), CategoryData( id: 2, label: 'سیاسی', asset: Assets.politicalCategoryIcon, ), CategoryData( id: 3, label: 'فناوری', asset: Assets.techCategoryIcon, ), CategoryData( id: 4, label: 'کسب و کار', asset: Assets.businessCategoryIcon, ), CategoryData( id: 5, label: 'زیست‌محیطی', asset: Assets.enviromentalCategoryIcon, ), CategoryData( id: 6, label: 'اجتماعی', asset: Assets.socialCategoryIcon, ), ]; } }