import 'dart:async'; import 'dart:math'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/news_details_data.dart'; import 'package:didvan/models/requests/news.dart'; import 'package:didvan/providers/core_provider.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; class NewsDetailsState extends CoreProvier { final List news = []; late final int initialIndex; late final NewsRequestArgs args; late Timer _trackingTimer; int _trackingTimerCounter = 0; int _currentIndex = 0; int get currentIndex => _currentIndex; NewsDetailsData get currentNews => news[_currentIndex]!; Future getNewsDetails(int id, {bool? isForward}) async { if (isForward == null) { appState = AppState.busy; } final service = RequestService(RequestHelper.newsDetails(id, args)); await service.httpGet(); _handleTracking(sendRequest: isForward != null); if (service.isSuccess) { final result = service.result; final newsItem = NewsDetailsData.fromJson(result['news']); if (args.page == 0) { news.add(newsItem); initialIndex = 0; appState = AppState.idle; return; } NewsDetailsData? prevNews; if (result['prevNews'].isNotEmpty) { prevNews = NewsDetailsData.fromJson(result['prevNews']); } NewsDetailsData? nextNews; if (result['nextNews'].isNotEmpty) { nextNews = NewsDetailsData.fromJson(result['nextNews']); } if (isForward == null) { news.addAll(List.generate(max(newsItem.order - 2, 0), (index) => null)); if (prevNews != null) { news.add(prevNews); } news.add(newsItem); if (nextNews != null) { news.add(nextNews); } _currentIndex = initialIndex = newsItem.order - 1; } else if (isForward) { if (!exists(nextNews) && nextNews != null) { news.add(nextNews); } _currentIndex++; } else if (!isForward) { if (!exists(prevNews) && prevNews != null) { news[_currentIndex - 2] = prevNews; } _currentIndex--; } appState = AppState.idle; return; } if (isForward == null) { appState = AppState.failed; } } bool exists(NewsDetailsData? newsItem) => news.any((n) => newsItem != null && n != null && n.id == newsItem.id); void onCommentsChanged(int count) { news.firstWhere((item) => item!.id == currentNews.id)!.comments = count; notifyListeners(); } Future _handleTracking({bool sendRequest = true}) async { if (!sendRequest) { _trackingTimer = Timer.periodic(const Duration(seconds: 1), (timer) { _trackingTimerCounter++; }); return; } //send request _trackingTimerCounter = 0; } @override void dispose() { _trackingTimer.cancel(); super.dispose(); } }