didvan-app/lib/views/podcasts/studio_details/studio_details_state.dart

228 lines
6.4 KiB
Dart

import 'dart:async';
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.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 {
late StudioDetailsData studio;
StudioDetailsData? nextStudio;
StudioDetailsData? prevStudio;
late int initialIndex;
StudioRequestArgs? args;
StudioRequestArgs? podcastArgs;
final List<int> relatedQueue = [];
bool _positionListenerActivated = false;
AppState alongSideState = AppState.idle;
int _trackingTimerCounter = 0;
Timer? _trackingTimer;
int _selectedDetailsIndex = 0;
Timer? timer;
int timerValue = 10;
bool stopOnPodcastEnds = false;
int get selectedDetailsIndex => _selectedDetailsIndex;
set selectedDetailsIndex(int value) {
_selectedDetailsIndex = value;
if (value == 2) {
getRelatedContents();
}
notifyListeners();
}
Future<void> getStudioDetails(
int id, {
StudioRequestArgs? args,
bool? isForward,
bool fetchOnly = false,
}) async {
try {
if (args != null) {
this.args = args;
}
if (this.args?.type == 'podcast') {
podcastArgs = this.args;
}
if (MediaService.currentPodcast?.id == id &&
this.args?.type == 'podcast' &&
!fetchOnly) {
return;
}
_selectedDetailsIndex = 0;
if (isForward != null) {
if (isForward) {
prevStudio = studio;
studio = nextStudio!;
nextStudio = null;
} else {
nextStudio = studio;
studio = prevStudio!;
prevStudio = null;
}
notifyListeners();
_handlePodcastPlayback(studio);
}
if (isForward == null) {
if (this.args?.type == 'podcast') {
MediaService.audioPlayerTag =
'podcast-${MediaService.currentPodcast?.id ?? ''}';
}
appState = AppState.busy;
} else {
alongSideState = AppState.busy;
notifyListeners();
}
final service = RequestService(
RequestHelper.studioDetails(
id,
this.args ?? const StudioRequestArgs(page: 0),
),
);
await service.httpGet();
nextStudio = null;
prevStudio = null;
if (stopOnPodcastEnds) {
timerValue = 10;
}
stopOnPodcastEnds = false;
if (service.isSuccess) {
if (args?.type == 'video') {
handleTracking(id: id, sendRequest: false);
}
final result = service.result;
studio = StudioDetailsData.fromJson(result['studio']);
if (args?.page == 0) {
initialIndex = 0;
appState = AppState.idle;
return;
}
if (result['nextStudio'].isNotEmpty && this.args?.page != 0) {
nextStudio = StudioDetailsData.fromJson(result['nextStudio']);
}
if (result['prevStudio'].isNotEmpty && this.args?.page != 0) {
prevStudio = StudioDetailsData.fromJson(result['prevStudio']);
}
if (isForward == null && !fetchOnly) {
await _handlePodcastPlayback(studio);
}
alongSideState = AppState.idle;
appState = AppState.idle;
return;
}
if (isForward == null) {
appState = AppState.failed;
} else {
alongSideState = AppState.failed;
notifyListeners();
}
} catch (e) {
// MediaService.resetAudioPlayer();
update();
appState = AppState.idle;
// rethrow;
}
}
Future<void> _handlePodcastPlayback(StudioDetailsData studio) async {
if (args?.type == 'podcast') {
MediaService.currentPodcast = studio;
MediaService.podcastPlaylistArgs = args;
await MediaService.handleAudioPlayback(
audioSource: studio.link,
id: studio.id,
isVoiceMessage: false,
onTrackChanged: (isNext) {
if (isNext && nextStudio != null) {
getStudioDetails(nextStudio!.id);
} else if (!isNext && prevStudio != null) {
getStudioDetails(prevStudio!.id);
}
},
);
if (nextStudio != null && !_positionListenerActivated) {
_positionListenerActivated = true;
MediaService.audioPlayer.positionStream.listen((event) {
if (MediaService.audioPlayerTag?.contains('message') == true) {
return;
}
final duration =
MediaService.duration ?? Duration(seconds: studio.duration);
if (event.compareTo(duration) > 0 && nextStudio != null) {
if (stopOnPodcastEnds) {
MediaService.resetAudioPlayer();
return;
}
getStudioDetails(nextStudio!.id, isForward: true);
}
});
}
} else {
MediaService.audioPlayer.pause();
// MediaService.audioPlayer.dispose();
}
}
Future<void> getRelatedContents() async {
if (studio.relatedContents.isNotEmpty) return;
relatedQueue.add(studio.id);
final service = RequestService(RequestHelper.tag(
ids: studio.tags.map((tag) => tag.id).toList(),
itemId: studio.id,
type: args?.type,
));
await service.httpGet();
if (service.isSuccess) {
final relateds = service.result['contents'];
for (var i = 0; i < relateds.length; i++) {
studio.relatedContents.add(OverviewData.fromJson(relateds[i]));
}
if (relateds.isEmpty) {
studio.relatedContentsIsEmpty = true;
}
} else {
studio.relatedContentsIsEmpty = true;
}
notifyListeners();
}
void onCommentsChanged(int count) {
studio.comments = count;
notifyListeners();
}
Future<void> handleTracking({
required int id,
bool sendRequest = true,
}) async {
if (!sendRequest) {
_trackingTimerCounter = 0;
_trackingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
_trackingTimerCounter++;
});
return;
}
final service = RequestService(
RequestHelper.tracking(id, 'studio'),
body: {
'sec': _trackingTimerCounter,
},
);
service.put();
_trackingTimerCounter = 0;
_trackingTimer?.cancel();
}
@override
void dispose() {
_trackingTimer?.cancel();
super.dispose();
}
}