import 'dart:async'; import 'dart:math'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/providers/core_provider.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request_helper.dart'; class StudioDetailsState extends CoreProvier { final List studios = []; late int initialIndex; late StudioRequestArgs args; bool isFetchingNewItem = false; final List relatedQueue = []; int _currentIndex = 0; int get currentIndex => _currentIndex; StudioDetailsData get currentStudio { try { return studios[_currentIndex]!; } catch (e) { return studios[_currentIndex + 1]!; } } Future getStudioDetails(int id, {bool? isForward, StudioRequestArgs? args}) async { if (args != null) { this.args = args; } if (isForward == null) { appState = AppState.busy; } else { isFetchingNewItem = true; notifyListeners(); } final service = RequestService(RequestHelper.studioDetails(id, this.args)); await service.httpGet(); if (service.isSuccess) { final result = service.result; final studio = StudioDetailsData.fromJson(result['studio']); if (this.args.page == 0) { studios.add(studio); initialIndex = 0; appState = AppState.idle; return; } if (this.args.type == 'podcast') { MediaService.currentPodcast = studio; MediaService.podcastPlaylistArgs = args; await MediaService.handleAudioPlayback( audioSource: studio.media, isVoiceMessage: false, ); } StudioDetailsData? prevStudio; if (result['prevStudio'].isNotEmpty) { prevStudio = StudioDetailsData.fromJson(result['prevStudio']); } StudioDetailsData? nextStudio; if (result['nextStudio'].isNotEmpty) { nextStudio = StudioDetailsData.fromJson(result['nextStudio']); } if (isForward == null) { studios .addAll(List.generate(max(studio.order - 2, 0), (index) => null)); if (prevStudio != null) { studios.add(prevStudio); } studios.add(studio); if (nextStudio != null) { studios.add(nextStudio); } _currentIndex = initialIndex = studio.order - 1; } else if (isForward) { if (!exists(nextStudio) && nextStudio != null) { studios.add(nextStudio); } _currentIndex++; } else if (!isForward) { if (!exists(prevStudio) && prevStudio != null) { studios[_currentIndex - 2] = prevStudio; } _currentIndex--; } isFetchingNewItem = false; appState = AppState.idle; return; } //why? total page state shouldn't die! if (isForward == null) { appState = AppState.failed; } } Future getRelatedContents() async { if (currentStudio.relatedContents.isNotEmpty) return; relatedQueue.add(currentStudio.id); final service = RequestService(RequestHelper.tag( ids: currentStudio.tags.map((tag) => tag.id).toList(), itemId: currentStudio.id, type: 'studio', )); await service.httpGet(); if (service.isSuccess) { final relateds = service.result['contents']; for (var i = 0; i < relateds.length; i++) { studios .where((element) => element != null) .firstWhere((element) => element!.id == currentStudio.id)! .relatedContents .add(OverviewData.fromJson(relateds[i])); } notifyListeners(); } } bool exists(StudioDetailsData? studio) => studios.any((r) => studio != null && r != null && r.id == studio.id); void onCommentsChanged(int count) { studios.firstWhere((studio) => studio?.id == currentStudio.id)!.comments = count; notifyListeners(); } }