You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
diplomatic-quarter/lib/services/course_service/course_service.dart

352 lines
12 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/course/education_journey_insert_model.dart';
import 'package:diplomaticquarterapp/models/course/education_journey_list_model.dart';
import 'package:diplomaticquarterapp/models/course/education_journey_model.dart';
import 'package:diplomaticquarterapp/pages/learning/question_sheet.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class CourseServiceProvider with ChangeNotifier {
AppSharedPreferences sharedPref = AppSharedPreferences();
AppGlobal appGlobal = AppGlobal();
AuthenticatedUser authUser = AuthenticatedUser();
AuthProvider authProvider = AuthProvider();
bool isDataLoaded = false;
int? selectedJourney;
List<Datum>? data;
PatientEducationJourneyListModel? nabedJourneyResponse;
PatientEducationJourneyModel? courseData;
List<Topic>? courseTopics;
Consultation? consultation;
List<Data>? playedData = [];
//Main Video Controller & Timer
VideoPlayerState _videoState = VideoPlayerState.paused;
VideoPlayerState get videoState => _videoState;
VideoPlayerController? controller;
Timer? timer;
// Learning Page
Future<dynamic> fetchPatientCoursesList() async {
print("====== Api Initiated =========");
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
request = {"Channel": 3, "TokenID": "@dm!n", "PatientID": 22335};
dynamic localRes;
await BaseAppClient().post(GET_PATIENT_COURSES_LIST, onSuccess: (response, statusCode) async {
print("====== Api Response =========");
print("${response["NabedJourneyResponseResult"]}");
localRes = PatientEducationJourneyListModel.fromJson(response);
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return localRes;
}
void getCourses(BuildContext context) async {
GifLoaderDialogUtils.showMyDialog(context);
dynamic response = await fetchPatientCoursesList();
GifLoaderDialogUtils.hideDialog(context);
if (response.nabedJourneyResponseResult != null) {
nabedJourneyResponse = response;
isDataLoaded = true;
data = nabedJourneyResponse!.nabedJourneyResponseResult!.data;
}
notifyListeners();
}
// Detailed Page
Future<dynamic> fetchPatientCourseById() async {
print("====== Api Initiated =========");
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
request = {"Channel": 3, "TokenID": "@dm!n", "JourneyID": selectedJourney};
dynamic localRes;
await BaseAppClient().post(GET_PATIENT_COURSE_BY_ID, onSuccess: (response, statusCode) async {
print("====== Api Response =========");
print("${response}");
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return localRes;
}
void getCourseById(BuildContext context) async {
GifLoaderDialogUtils.showMyDialog(context);
dynamic response = await fetchPatientCourseById();
GifLoaderDialogUtils.hideDialog(context);
if (response != null) {
courseData = PatientEducationJourneyModel.fromRawJson(jsonEncode(response));
courseTopics = courseData!.nabedJourneyByIdResponseResult!.contentClasses!.first.topics;
consultation = courseData!.nabedJourneyByIdResponseResult!.consultation;
}
notifyListeners();
}
Future navigate(BuildContext context, int journey, {required Function(Object? val) onBack}) async {
selectedJourney = journey;
Navigator.of(context).pushNamed(COURSES_DETAILED_PAGE).then((val) {
onBack(val);
});
}
String getDurationOfVideo(int duration) {
final durationInSeconds = duration;
final minutes = durationInSeconds ~/ 60;
final seconds = durationInSeconds % 60;
return "$minutes:${seconds.toString().padLeft(2, '0')} mins";
}
void playVideo(BuildContext context, {required Content content}) async {
print("OnTap");
if (_videoState == VideoPlayerState.playing) {
controller?.pause();
setVideoState(VideoPlayerState.paused);
} else {
setVideoState(VideoPlayerState.loading);
notifyListeners();
try {
final videoUrl = content.video?.flavor?.downloadable ?? "";
if (videoUrl.isEmpty) {
Utils.showErrorToast("No video URL provided.");
setVideoState(VideoPlayerState.paused);
return;
}
controller = VideoPlayerController.networkUrl(
Uri.parse(videoUrl),
//formatHint: VideoFormat.hls,
);
await controller!.initialize();
controller!.play();
setVideoState(VideoPlayerState.playing);
notifyListeners();
content.controller = controller;
controller!.addListener(() {
if (controller!.value.isPlaying && timer == null) {
_startTimer(context, content: content);
} else if (!controller!.value.isPlaying && timer != null) {
stopTimer();
}
if (controller!.value.hasError) {
Utils.showErrorToast("Failed to load video.");
controller = null;
setVideoState(VideoPlayerState.paused);
notifyListeners();
}
});
} catch (e) {
Utils.showErrorToast("Error loading video: $e");
controller = null;
setVideoState(VideoPlayerState.paused);
notifyListeners();
}
}
}
void setVideoState(VideoPlayerState state) {
_videoState = state;
notifyListeners();
}
void _startTimer(BuildContext context, {required Content content}) {
timer = Timer.periodic(Duration(seconds: 1), (timer) async {
if (controller != null && _videoState == VideoPlayerState.playing) {
final position = await controller!.position;
if (position != null) {
print("Current position: ${position.inSeconds} seconds");
notifyListeners();
if (position.inSeconds == content.question!.triggerAt) {
controller!.pause();
setVideoState(VideoPlayerState.paused);
QuestionSheetAction? action = await showQuestionSheet(context, content: content);
if (action == QuestionSheetAction.skip) {
controller!.play();
setVideoState(VideoPlayerState.playing);
} else if (action == QuestionSheetAction.rewatch) {
playVideo(context, content: content);
}
}
}
}
});
}
void stopTimer() {
timer?.cancel();
timer = null;
}
Future<void> uploadStats() async {
// if(courseTopics != null) {
// Future.forEach(courseTopics!, (topic) {
// Future.forEach(topic.contents!, (content){
// content.controller
// });
// });
// }
if (courseTopics != null) {
await Future.forEach(courseTopics!, (topic) async {
await Future.forEach(topic.contents!, (content) {
print(content.controller?.value);
playedData!.add(new Data(
type: "content_watch",
consultationId: 2660,
contentClassId: 46,
contentId: 322,
topicId: 6,
percentage: content.controller?.value.position.inSeconds ?? 0,
flavorId: 1,
srcType: "educate-external",
screenType: "journey_screen",
));
});
});
}
print("===============");
print(playedData.toString());
print("===============");
}
// void playVideo(BuildContext context, {required Content content}) async {
// print("OnTap");
// if (_videoState == VideoPlayerState.playing) {
// controller?.pause();
// setVideoState(VideoPlayerState.paused);
// } else {
// try {
// controller = VideoPlayerController.networkUrl(
// Uri.parse(
// Platform.isIOS ? content.video!.flavor!.downloadable! : content.video!.flavor!.downloadable!,
// ),
// formatHint: VideoFormat.hls)
// ..initialize()
// ..play();
// notifyListeners();
// content.controller = controller;
// notifyListeners();
// controller!.addListener(() {
// if (controller!.value.isPlaying && timer == null) {
// startTimer(context, content: content);
// notifyListeners();
// } else if (!controller!.value.isPlaying && timer != null) {
// stopTimer();
// notifyListeners();
// }
// });
//
// controller!.addListener(() {
// if (controller!.value.hasError) {
// Utils.showErrorToast("Failed to load video.");
// controller = null;
// setVideoState(VideoPlayerState.paused);
// notifyListeners();
// }
// });
// notifyListeners();
// } catch (e) {
// Utils.showErrorToast("Error loading video: $e");
// controller = null;
// setVideoState(VideoPlayerState.paused);
// notifyListeners();
// }
// controller?.play();
// setVideoState(VideoPlayerState.playing);
// }
// }
//
//
// void setVideoState(VideoPlayerState state) {
// _videoState = state;
// notifyListeners();
// }
//
// void startTimer(BuildContext context, {required Content content}) {
// timer = Timer.periodic(Duration(seconds: 1), (timer) async {
// if (controller != null && _videoState == VideoPlayerState.playing) {
// final position = await controller!.position;
// if (position != null) {
// print("Current position: ${position.inSeconds} seconds");
// if (position.inSeconds == content.question!.triggerAt) {
// print("position: ${position.inSeconds} - ${content.question!.triggerAt} seconds");
// controller!.pause();
// setVideoState(VideoPlayerState.paused);
// QuestionSheetAction? action = await showQuestionSheet(context, content: content);
// if (action == QuestionSheetAction.skip) {
// print("Skip");
// controller!.play();
// } else if (action == QuestionSheetAction.rewatch) {
// print("Re-watch");
// playVideo(context, content: content);
// }
// }
// notifyListeners();
// }
// }
// });
// }
//
// void stopTimer() {
// timer?.cancel();
// timer = null;
// }
// void onComplete() {
// stopTimer();
// setVideoState(VideoPlayerState.completed);
// }
Future<void> clearData() async {
data = courseData = nabedJourneyResponse = selectedJourney = courseTopics = consultation = timer = controller = null;
}
Future<void> clear() async {
if (controller != null) controller!.dispose();
courseData = courseTopics = timer = controller = null;
}
}
enum VideoPlayerState { playing, paused, completed, loading }
IconData getVideoIcon(VideoPlayerState state) {
switch (state) {
case VideoPlayerState.loading:
return Icons.hourglass_top;
case VideoPlayerState.playing:
return Icons.pause;
case VideoPlayerState.paused:
return Icons.play_arrow;
case VideoPlayerState.completed:
return Icons.replay;
default:
return Icons.play_arrow;
}
}