import 'dart:async'; import 'dart:math'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/radar_details_data.dart'; import 'package:didvan/models/requests/radar.dart'; import 'package:didvan/providers/core.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; class RadarDetailsState extends CoreProvier { final List radars = []; late Timer _trackingTimer; int _trackingTimerCounter = 0; late final int initialIndex; late final RadarRequestArgs args; bool isFetchingNewItem = false; final List relatedQueue = []; int _currentIndex = 0; int get currentIndex => _currentIndex; RadarDetailsData get currentRadar { try { return radars[_currentIndex]!; } catch (e) { return radars[_currentIndex + 1]!; } } Future getRadarDetails(int id, {bool? isForward}) async { if (isForward == null) { appState = AppState.busy; } else { isFetchingNewItem = true; notifyListeners(); } final service = RequestService(RequestHelper.radarDetails(id, args)); await service.httpGet(); _handleTracking(sendRequest: isForward != null); if (service.isSuccess) { final result = service.result; final radar = RadarDetailsData.fromJson(result['radar']); if (args.page == 0) { radars.add(radar); initialIndex = 0; appState = AppState.idle; return; } RadarDetailsData? prevRadar; if (result['prevRadar'].isNotEmpty) { prevRadar = RadarDetailsData.fromJson(result['prevRadar']); } RadarDetailsData? nextRadar; if (result['nextRadar'].isNotEmpty) { nextRadar = RadarDetailsData.fromJson(result['nextRadar']); } if (isForward == null) { radars.addAll(List.generate(max(radar.order - 2, 0), (index) => null)); if (prevRadar != null) { radars.add(prevRadar); } radars.add(radar); if (nextRadar != null) { radars.add(nextRadar); } _currentIndex = initialIndex = radar.order - 1; } else if (isForward) { if (!exists(nextRadar) && nextRadar != null) { radars.add(nextRadar); } _currentIndex++; } else if (!isForward) { if (!exists(prevRadar) && prevRadar != null) { radars[_currentIndex - 2] = prevRadar; } _currentIndex--; } isFetchingNewItem = false; appState = AppState.idle; return; } //why? total page state shouldn't die! if (isForward == null) { appState = AppState.failed; } } Future getRelatedContents() async { if (currentRadar.relatedContents.isNotEmpty) return; relatedQueue.add(currentRadar.id); final service = RequestService(RequestHelper.tag( ids: currentRadar.tags.map((tag) => tag.id).toList(), itemId: currentRadar.id, type: 'radar', )); await service.httpGet(); if (service.isSuccess) { final relateds = service.result['contents']; for (var i = 0; i < relateds.length; i++) { radars .where((element) => element != null) .firstWhere((element) => element!.id == currentRadar.id)! .relatedContents .add(OverviewData.fromJson(relateds[i])); } notifyListeners(); } } bool exists(RadarDetailsData? radar) => radars.any((r) => radar != null && r != null && r.id == radar.id); void onCommentsChanged(int count) { radars.firstWhere((radar) => radar?.id == currentRadar.id)!.comments = count; notifyListeners(); } Future _handleTracking({bool sendRequest = true}) async { if (!sendRequest) { _trackingTimerCounter = 0; _trackingTimer = Timer.periodic(const Duration(seconds: 1), (timer) { _trackingTimerCounter++; }); return; } final service = RequestService( RequestHelper.tracking(currentRadar.id, 'radar'), body: { 'sec': _trackingTimerCounter, }, ); service.put(); _trackingTimerCounter = 0; _trackingTimer.cancel(); } @override void dispose() { _handleTracking(sendRequest: true); _trackingTimer.cancel(); super.dispose(); } }