// import 'dart:html'; import 'dart:ffi'; import 'dart:io'; import 'package:cherry_toast/cherry_toast.dart'; import 'package:cherry_toast/resources/arrays.dart'; import 'package:easy_image_viewer/easy_image_viewer.dart'; import 'package:floating/floating.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:initial_folder/main.dart'; import 'package:http/http.dart' as http; import 'package:flutter_text_viewer/flutter_text_viewer.dart'; import 'package:initial_folder/models/section_model.dart'; import 'package:initial_folder/providers/certificate_provider.dart' as certifProvider; import 'package:initial_folder/providers/lesson_course_provider.dart'; import 'package:initial_folder/providers/my_course_provider.dart' as myCourseProvider; import 'package:initial_folder/providers/play_video_course_provider.dart'; import 'package:initial_folder/providers/selected_title_provider.dart'; import 'package:initial_folder/screens/course/component/announcement.dart'; import 'package:initial_folder/screens/course/component/detail_play_course.dart'; import 'package:initial_folder/screens/course/component/pdfReader.dart'; import 'package:initial_folder/screens/course/component/quest_and_answer.dart'; import 'package:initial_folder/screens/course/component/txtReader.dart'; import 'package:initial_folder/screens/course/quiz_page.dart'; import 'package:initial_folder/screens/course/sertif.dart'; import 'package:initial_folder/services/lesson_course_service.dart'; import 'package:initial_folder/size_config.dart'; import 'package:initial_folder/theme.dart'; import 'package:initial_folder/widgets/custom_expansion_tile.dart'; import 'package:open_file/open_file.dart'; import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:youtube_player_flutter/youtube_player_flutter.dart'; import 'package:chewie/chewie.dart'; import 'package:video_player/video_player.dart'; import './component/expansion_tile_copy.dart'; class PlayCourseOld extends StatefulWidget { const PlayCourseOld( {Key? key, required this.instruktur, required this.judul, required this.thumbnail, required this.courseeid, this.isQna}) : super(key: key); final String judul, instruktur, thumbnail, courseeid; final bool? isQna; @override State createState() => _PlayCoursePageState(); } class _PlayCoursePageState extends State with SingleTickerProviderStateMixin, WidgetsBindingObserver { late TabController _tabController; LessonCourseService lessonCourseService = LessonCourseService(); late YoutubePlayerController _controller; late PlayerState _playerState; late YoutubeMetaData _videoMetaData; bool _isPlayerReady = false; int totalProgress = 0; bool _isvideoClicked = false; bool _isyt = true; String linkhtml5 = ''; bool _gabisaskip = false; List dataLesson = []; final floating = Floating(); var _selectedIndex = 0; int? _expandedTileIndex; final _tileKeys = []; String formatDuration(String duration) { if (duration == '') { String formattedDuration = ''; print('masuk sini'); formattedDuration += ''; return formattedDuration; } List parts = duration.split(':'); int hours = int.parse(parts[0]); int minutes = int.parse(parts[1]); int seconds = int.parse(parts[2]); String formattedDuration = ''; if (hours != 0) { formattedDuration += '${hours}j'; } if (minutes != 0) { formattedDuration += '${int.parse(parts[1])}m'; } formattedDuration += '${int.parse(parts[2])}d'; return formattedDuration; } String courseID_local_end = ''; String lessonID_local_end = ''; late ChewieController _chewieController; VideoPlayerController _videoPlayerController = VideoPlayerController.network( 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'); @override void initState() { super.initState(); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); WidgetsBinding.instance.addObserver(this); _tabController = TabController( vsync: this, length: 4, initialIndex: (widget.isQna == true) ? 2 : 0); _controller = YoutubePlayerController( //todo initialVideoId: YoutubePlayer.convertUrlToId('') ?? '', flags: const YoutubePlayerFlags( mute: false, disableDragSeek: false, loop: false, isLive: false, forceHD: false, enableCaption: false, autoPlay: true, hideThumbnail: true, ), ); _chewieController = ChewieController( videoPlayerController: _videoPlayerController, autoPlay: true, looping: false, aspectRatio: 16 / 9, // Other ChewieController configurations... ); } void _initializeytController(String url) async { setState(() { _controller = YoutubePlayerController( //todo initialVideoId: YoutubePlayer.convertUrlToId(url).toString(), flags: const YoutubePlayerFlags( mute: false, disableDragSeek: false, loop: false, isLive: false, forceHD: false, enableCaption: false, autoPlay: true, hideThumbnail: true, ), ); }); } void _initializeChewieController(String videoUrl) async { _videoPlayerController = VideoPlayerController.network(videoUrl); // await _videoPlayerController.initialize(); setState(() { _chewieController = ChewieController( videoPlayerController: _videoPlayerController, autoPlay: true, looping: false, aspectRatio: 16 / 9, additionalOptions: (context) { return [ OptionItem( onTap: () { enablePip(); Navigator.pop(context); }, iconData: Icons.picture_in_picture, title: 'Aktifkan mode PiP', ), ]; }, // customControls: CustomChewieControls() // Other ChewieController configurations... ); //todo _videoPlayerController.addListener(() async { if (_videoPlayerController.value.position == _videoPlayerController.value.duration) { print('video Ended'); print(widget.courseeid); print(lessonID_local_end); LessonCourseService() .updateLessonCourse(lessonID_local_end) .then((value) => { if (value == 201) {print('berhasil')} }); await Provider.of(context, listen: false) .getMyCourse(); setState(() { print('DIBAWAH CUY'); _gabisaskip = false; dataLesson .map((e) => e) .where((element) => element.lessonId == lessonID_local_end) .first .isFinished = 1; }); // print('g masuk'); } }); }); } @override void dispose() { _chewieController.dispose(); _videoPlayerController.dispose(); WidgetsBinding.instance.removeObserver(this); floating.dispose(); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState lifecycleState) { super.didChangeAppLifecycleState(lifecycleState); // if (lifecycleState == AppLifecycleState.inactive) { // floating.enable(Rational.landscape()); // } if (lifecycleState == AppLifecycleState.resumed) { // Aplikasi kembali dari background (termasuk dari mode PiP) // Menampilkan status bar kembali SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); } } Future enablePip() async { final status = await floating.enable(Rational.landscape()); debugPrint('Pipenable? $status'); } @override void deactivate() { // Pauses video while navigating to next page. _controller.pause(); // _chewieController.pause(); super.deactivate(); } // void listener() { // if (_isPlayerReady && mounted && !_controller.value.isFullScreen) { // setState(() { // _playerState = _controller.value.playerState; // _videoMetaData = _controller.metadata; // }); // } // if (_playerState == PlayerState.ended) { // print('Video telah selesai diputar'); // } // } void loadImage(String link) async { final imageProvider = Image.network("https://api.vokasia.id/uploads/lesson_files/" + link) .image; showImageViewer(context, imageProvider, doubleTapZoomable: true, onViewerDismissed: () { print("dismissed"); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); }); } Future openFileFromUrl(BuildContext context, String fileUrl) async { try { print(fileUrl); final response = await http.get( Uri.parse('https://api.vokasia.id/uploads/lesson_files/$fileUrl')); if (response.statusCode == 200) { final fileBytes = response.bodyBytes; final fileName = fileUrl.split('/').last; final fileType = 'txt'; // Sesuaikan dengan tipe file yang ingin dibuka final tempDir = await getTemporaryDirectory(); final tempFilePath = '${tempDir.path}/$fileName'; await File(tempFilePath).writeAsBytes(fileBytes); print(tempFilePath); OpenFile.open(tempFilePath); // Buka file menggunakan aplikasi default pada perangkat // Contoh: OpenFile.open(tempFilePath); } else { print('Failed to download file: ${response.statusCode}'); } } catch (e) { print('Error opening file from URL: $e'); } } void resetExpansionTileKeysAndSelectedIndex() { _tileKeys.clear(); _selectedIndex = 0; } @override Widget build(BuildContext context) { final Brightness brightnessValue = MediaQuery.of(context).platformBrightness; bool isDarkMode = brightnessValue == Brightness.dark; String _parseHtmlString(String htmlText) { RegExp exp = RegExp(r"<[^>]*>| |&|"", multiLine: true, caseSensitive: true); return htmlText.replaceAll(exp, ''); } resetExpansionTileKeysAndSelectedIndex(); final selectedTitleProvider = Provider.of(context); PlayVideoCourseProvider playVideoCourseProvider = Provider.of(context); var dataProgress = Provider.of(context); // var dataProgress22 = Provider.of(context).courseService; _getTab(index, child) { return Tab( height: 30, iconMargin: EdgeInsets.zero, child: Container( child: Center( child: Text( child, style: primaryTextStyle.copyWith( fontSize: SizeConfig.blockHorizontal! * 3.2, letterSpacing: 0.4, ), ), ), ), ); } _ceklisattachment( String lessonId, String idCourse, int isFinished, ) async { print('ini lesson id ->' + lessonId); print('ini course id ->' + idCourse); await lessonCourseService.updateLessonCourse(lessonId).then((value) => { print('ini value dari sana' + value.toString()), if (value == '201') setState(() { { isFinished = 1; } }) }); await Provider.of(context, listen: false) .getMyCourse(); setState(() { print('DIBAWAH CUY'); dataLesson .map((e) => e) .where((element) => element.lessonId == lessonId) .first .isFinished = 1; }); } // Widget cekbox( // int isFinished, String isSkipped, String courseId, String lessonId) { // return Checkbox( // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), // activeColor: primaryColor, // value: (isFinished == 1) ? true : false, // onChanged: (value) { // if (isSkipped == '1') { // Provider.of(context) // .updateLessonCourse(courseId, lessonId); // } // }); // } Duration getVideoDuration(String duration) { int hours = 0; int minutes = 0; int seconds = 0; List timeSplit = duration.split(':'); hours = int.parse(timeSplit[0]); minutes = int.parse(timeSplit[1]); seconds = int.parse(timeSplit[2]); return Duration(hours: hours, minutes: minutes, seconds: seconds - 1); } Widget cekbox( int isFinished, String isSkipped, String lessonId, Map lessonMapId, List dataLesson, String lessontypeee, String videotypeee, String idCourse) { return Theme( data: Theme.of(context).copyWith(unselectedWidgetColor: Colors.grey), child: Checkbox( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4)), activeColor: primaryColor, checkColor: Colors.white, value: (isFinished == 1) ? true : false, onChanged: (value) async { // print(lessontypeee); var data = dataLesson .map((e) => e) .where((lesson) => lesson.lessonId == lessonMapId['${playVideoCourseProvider.url}']) .first; if (lessontypeee != 'video') { //todo if (isSkipped == '0') { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Anda tidak dapat mencentang pelajaran\nyang tidak dapat diskip', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } else { print('ini lesson id ->' + lessonId); print('ini course id ->' + idCourse); await lessonCourseService .updateLessonCourse(lessonId) .then((value) => { print('ini value dari sana' + value.toString()), if (value == '201') setState(() { { isFinished = 1; } }) }); await Provider.of( context, listen: false) .getMyCourse(); setState(() { print('DIBAWAH CUY'); dataLesson .map((e) => e) .where((element) => element.lessonId == lessonId) .first .isFinished = 1; }); } } else if (videotypeee == 'html5') { print('ceklis html5 diklik'); if (isSkipped == '1') { _chewieController.seekTo(getVideoDuration(data.duration!)); } else if (isSkipped == '0') { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Video Tidak dapat dilewati', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } } if (lessonId == lessonMapId['${playVideoCourseProvider.url}'] && lessonId != '') { if (isSkipped == '1') { print('masuk kesini'); _controller.seekTo(getVideoDuration(data.duration!)); } else if (isSkipped == '0') { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Video Tidak dapat dilewati', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } } })); } Widget tileKursus( Key tileKeyoper, int index, List lesonOper, Iterable sectionOper, Datum e, Map lessonMapIdoper, List dataLessonOper) { return ListTileTheme( dense: true, child: Container( margin: EdgeInsets.symmetric(horizontal: 15, vertical: 5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Theme.of(context).colorScheme.primaryContainer, boxShadow: [ BoxShadow( color: Theme.of(context).brightness == Brightness.dark ? Colors.black : Colors.grey, spreadRadius: 0.01, blurRadius: 1, offset: Offset(0, 1), // Shadow position ), ], ), child: ExpansionTileCopy( key: tileKeyoper, initiallyExpanded: index == _expandedTileIndex, onExpansionChanged: (value) { // If tile is expanding, then collapse the already expanded tile. if (value) { if (index != _selectedIndex) { _tileKeys[_selectedIndex].currentState!.closeExpansion(); } _selectedIndex = index; } }, title: Text( 'Bab ${index + 1}', style: thirdTextStyle.copyWith( fontWeight: bold, letterSpacing: 0.5, color: Theme.of(context).colorScheme.onBackground, fontSize: getProportionateScreenWidth(12)), ), subtitle: Html( shrinkWrap: true, data: e.sectionTitle, style: { "body": Style( margin: Margins.zero, padding: HtmlPaddings.zero, fontSize: FontSize(getProportionateScreenWidth(12)), fontWeight: semiBold, letterSpacing: 0.5, fontFamily: 'Poppins', color: Theme.of(context).colorScheme.onBackground), }, ), children: e.dataLesson! .asMap() .entries .map( (e) => Container( margin: EdgeInsets.only( left: getProportionateScreenWidth(10), right: getProportionateScreenWidth(20), bottom: getProportionateScreenHeight(5)), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10)), child: GestureDetector( onTap: _isPlayerReady ? (e.value.videoType == 'youtubelink' || e.value.videoType == 'YouTube') ? () { print('masuk sini'); setState(() { _isvideoClicked = true; _isPlayerReady = true; }); selectedTitleProvider.selectedTitle = e.value.title; Announcement announcement = Announcement( id: lesonOper .map((e) => e.courseId ?? '') .toList() .first, lesonOper: lesonOper, sectionOper: sectionOper, lessonMapIdoper: lessonMapIdoper, dataLessonOper: dataLessonOper, ); announcement.showSummary(e.value.title); print(_gabisaskip); if (_gabisaskip == true) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Video Tidak dapat dilewati', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } else { if (e.value.isSkip == '1') { setState(() { _gabisaskip = false; playVideoCourseProvider.indexUri( YoutubePlayer.convertUrlToId( e.value.videoUrl ?? '') ?? ''); if (_isyt == false) { _initializeytController( playVideoCourseProvider.url); _isyt = true; } else { _controller.load( YoutubePlayer.convertUrlToId( playVideoCourseProvider .url) ?? '', ); _isyt = true; } _isyt = true; }); } else if (e.value.isSkip == '0' && e.value.isFinished == 1) { setState(() { _gabisaskip = false; playVideoCourseProvider.indexUri( YoutubePlayer.convertUrlToId( e.value.videoUrl ?? '') ?? ''); if (_isyt == false) { _initializeytController( playVideoCourseProvider.url); _isyt = true; } else { _controller.load( YoutubePlayer.convertUrlToId( playVideoCourseProvider .url) ?? '', ); _isyt = true; } _isyt = true; }); } else if (e.value.isSkip == '0' && e.value.isFinished == 0) { //todo setState(() { _gabisaskip = true; playVideoCourseProvider.indexUri( YoutubePlayer.convertUrlToId( e.value.videoUrl ?? '') ?? ''); if (_isyt == false) { _initializeytController( playVideoCourseProvider.url); _isyt = true; } else { _controller.load( YoutubePlayer.convertUrlToId( playVideoCourseProvider .url) ?? '', ); _isyt = true; } _isyt = true; }); } } } : (e.value.videoType == 'html5') ? () { setState(() { _isvideoClicked = true; _isPlayerReady = true; }); print(_gabisaskip); if (_gabisaskip == true) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Video Tidak dapat dilewati', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } else { if (e.value.isSkip == '1') { setState(() { _gabisaskip = false; setState(() { //todo print(e.value.courseId); courseID_local_end = e.value.courseId.toString(); lessonID_local_end = e.value.lessonId.toString(); print(e.value.videoUrl); _isyt = false; _initializeChewieController( '${e.value.videoUrl}', ); }); }); } else if (e.value.isSkip == '0' && e.value.isFinished == 1) { setState(() { _gabisaskip = false; setState(() { //todo print(e.value.courseId); courseID_local_end = e.value.courseId.toString(); lessonID_local_end = e.value.lessonId.toString(); print(e.value.videoUrl); _isyt = false; _initializeChewieController( '${e.value.videoUrl}', ); }); }); } else if (e.value.isSkip == '0' && e.value.isFinished == 0) { //todo setState(() { _gabisaskip = true; setState(() { //todo print(e.value.courseId); courseID_local_end = e.value.courseId.toString(); lessonID_local_end = e.value.lessonId.toString(); print(e.value.videoUrl); _isyt = false; _initializeChewieController( '${e.value.videoUrl}', ); }); }); } } } : () { (e.value.lessonType == 'quiz') ? { print('ini quiz'), (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController .pause() }, _ceklisattachment( e.value.lessonId.toString(), widget.courseeid, e.value.isFinished!), Navigator.push( context, MaterialPageRoute( builder: (context) => quizPage( judulQuiz: e.value.title .toString(), lessonId: e .value.lessonId .toString(), ), )) } : (e.value.attachment .toString() .contains('.pdf')) ? { print('ini pdf'), (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController .pause() }, _ceklisattachment( e.value.lessonId .toString(), widget.courseeid, e.value.isFinished!), // print(e.value.lessonId.toString()), // print(widget.courseeid), // print(e.value.isFinished.toString()), // _chewieController.pause(), Navigator.push( context, MaterialPageRoute( builder: (context) => pdfReader( link: e.value .attachment, title: e.value.title .toString(), ), )) } : (e.value.attachment .toString() .contains( '.xlsx')) || (e.value.attachment .toString() .contains('.xls')) ? { (_isyt == true) ? { _controller .pause(), } : { _videoPlayerController .pause() }, _ceklisattachment( e.value.lessonId .toString(), widget.courseeid, e.value .isFinished!), openFileFromUrl(context, e.value.attachment) } : (e.value.attachment .toString() .contains( '.pptx')) || (e.value.attachment .toString() .contains( '.ppt')) ? { (_isyt == true) ? { _controller .pause(), } : { _videoPlayerController .pause() }, _ceklisattachment( e.value.lessonId .toString(), widget .courseeid, e.value .isFinished!), openFileFromUrl( context, e.value .attachment) } : (e.value.attachment .toString() .contains( '.rar')) ? { (_isyt == true) ? { _controller .pause(), } : { _videoPlayerController .pause() }, _ceklisattachment( e.value .lessonId .toString(), widget .courseeid, e.value .isFinished!), openFileFromUrl( context, e.value .attachment) } : (e.value .attachment .toString() .contains( '.zip')) ? { (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController.pause() }, _ceklisattachment( e.value .lessonId .toString(), widget .courseeid, e.value .isFinished!), openFileFromUrl( context, e.value .attachment) } : (e.value.attachment.toString().contains('.docx')) ? { (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController.pause() }, _ceklisattachment( e.value.lessonId.toString(), widget.courseeid, e.value.isFinished!), openFileFromUrl( context, e.value.attachment) } : ((e.value.attachment.toString().contains('.jpg') || e.value.attachment.toString().contains('.jpeg') || e.value.attachment.toString().contains('.png'))) ? { (e.value.attachment == null) ? { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Dokumen Belum Tersedia', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )) } : { print('ini image'), // _controller.pause(), (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController.pause() }, _ceklisattachment(e.value.lessonId.toString(), widget.courseeid, e.value.isFinished!), loadImage(e.value.attachment) }, } : (e.value.attachment.toString().contains('.txt')) ? { (e.value.attachment == null) ? { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Dokumen Belum Tersedia', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )) } : { print('ini text'), (_isyt == true) ? { _controller.pause(), } : { _videoPlayerController.pause() }, _ceklisattachment(e.value.lessonId.toString(), widget.courseeid, e.value.isFinished!), openFileFromUrl(context, e.value.attachment) }, } : ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Bukan video url ', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); } : () { ScaffoldMessenger.of(context) .showSnackBar(SnackBar( duration: Duration(seconds: 2), backgroundColor: primaryColor, content: Text( 'Mohon tunggu player belum siap ', textAlign: TextAlign.center, style: primaryTextStyle.copyWith( color: backgroundColor, ), ), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), )); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ cekbox( e.value.isFinished ?? 0, e.value.isSkip ?? '0', e.value.lessonId ?? '', lessonMapIdoper, dataLessonOper, e.value.lessonType.toString(), e.value.videoType.toString(), widget.courseeid), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( // color: Colors.amber, width: getProportionateScreenWidth(190), child: Text( _parseHtmlString( e.value.title.toString()), style: thirdTextStyle.copyWith( fontSize: 12, color: Theme.of(context) .colorScheme .onBackground, // letterSpacing: 0.5, ), ), ), Text( (e.value.lessonType == 'video') ? 'Video - ${formatDuration(e.value.duration.toString())}' : (e.value.lessonType == 'quiz') ? 'Quiz' : (e.value.attachment .toString() .contains('.pdf')) ? 'PDFs' : (e.value.attachment .toString() .contains('.pptx')) ? 'PPT' : (e.value.attachment .toString() .contains('.rar')) ? 'RAR' : (e.value.attachment .toString() .contains( '.zip')) ? 'ZIP' : (e.value .attachment .toString() .contains( '.xlsx')) ? 'Excel' : (e.value.attachment.toString().contains('.jpg') || e.value .attachment .toString() .contains( '.jpeg') || e.value .attachment .toString() .contains( '.png')) ? 'Image' : (e.value .attachment .toString() .contains('.docx')) ? 'Document' : (e.value.attachment.toString().contains('.txt')) ? 'Text' : 'Terjadi Kesalahan', style: TextStyle( fontSize: 10, color: Theme.of(context) .colorScheme .onBackground, letterSpacing: 0.5, fontFamily: 'Noto Sans', ), ), ], ), Spacer(), if (e.value.lessonType == 'video') Image.asset( 'assets/images/play_button_new.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(3), ) else if (e.value.lessonType == 'quiz') Image.asset( 'assets/icons/lms/ListNumbers.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.pdf')) Image.asset( 'assets/icons/lms/FilePdf.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.rar')) Image.asset( 'assets/icons/lms/FileArchive.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.zip')) Image.asset( 'assets/icons/lms/FileZip.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.pptx')) Image.asset( 'assets/icons/lms/FilePpt.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.xlsx')) Image.asset( 'assets/icons/lms/FileXls.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.jpg') || e.value.attachment .toString() .contains('.jpeg') || e.value.attachment .toString() .contains('.png')) Image.asset( 'assets/icons/lms/FileImage.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if (e.value.attachment .toString() .contains('.txt')) Image.asset( 'assets/icons/lms/FileText.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else if ((e.value.attachment .toString() .contains('.docx'))) Image.asset( 'assets/icons/lms/FileDoc.png', color: Theme.of(context) .colorScheme .onBackground, scale: getProportionateScreenWidth(1.3), ) else SizedBox(), ], ), ], ), ), ), ) .toList(), ), )); } Widget tabbarbawah( BuildContext context, List lesonOper, Iterable sectionOper, Map lessonMapIdoper, List dataLessonOper) { return DefaultTabController( length: 4, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( color: Theme.of(context).colorScheme.background, boxShadow: [ BoxShadow( color: Theme.of(context).brightness == Brightness.dark ? Colors.black : Colors.grey, spreadRadius: 0.05, blurRadius: 5, offset: Offset(0, 1), // Shadow position ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: getProportionateScreenHeight(10), ), Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(15)), child: Text( '${widget.judul}', textAlign: TextAlign.start, style: thirdTextStyle.copyWith( letterSpacing: 1, fontSize: getProportionateScreenWidth(14), fontWeight: semiBold), ), ), Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(16), vertical: getProportionateScreenHeight(8)), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('${widget.instruktur}', style: thirdTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), color: isDarkMode ? Color(0xff727272) : Color(0xff727272), )), GestureDetector( onTap: () { _controller.pause(); _videoPlayerController.pause(); Navigator.of(context, rootNavigator: true).push( MaterialPageRoute( builder: (context) => Sertif( totalProgress: totalProgress, idCourse: int.parse(widget.courseeid), ), ), ); }, child: Row( children: [ Image.asset( 'assets/images/certificate_icon.png', scale: getProportionateScreenWidth(1.3), ), SizedBox( width: 5, ), Text( 'Sertifikat', style: thirdTextStyle.copyWith( color: primaryColor), ) ], ), ) ], ), ), Consumer( builder: (context, state, _) { var progres = state.result!.data[0] .map((e) => e) .where( (element) => element.courseId == lesonOper .map((e) => e.courseId ?? '') .toList() .first, ) .toList(); print(progres[0]); double progressWidth = (SizeConfig.screenWidth - getProportionateScreenWidth(20)) * int.parse(progres[0].totalProgress.toString()) / 100; print("ini progres width" + progressWidth.toString()); totalProgress = progres[0].totalProgress!; return (progressWidth == 0.0) ? Padding( padding: EdgeInsets.only( left: progressWidth, // : progressWidth > 390 // ? progressWidth - 25 // : progressWidth - 10, ), child: Container( width: getProportionateScreenWidth(35), height: getProportionateScreenHeight(15), // padding: EdgeInsets.only(left: progressWidth - 5), decoration: BoxDecoration( color: primaryColor, borderRadius: BorderRadius.circular(5)), child: Center( child: Text( '${progres[0].totalProgress}%', style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), fontWeight: reguler, color: Colors.white, letterSpacing: 0.5, ), ), ))) : (progressWidth > 390) ? Align( alignment: Alignment.centerRight, child: Padding( padding: EdgeInsets.only( right: getProportionateScreenWidth(10), // : progressWidth > 390 // ? progressWidth - 25 // : progressWidth - 10, ), child: Container( width: getProportionateScreenWidth(35), height: getProportionateScreenHeight(15), // padding: EdgeInsets.only(left: progressWidth - 5), decoration: BoxDecoration( color: primaryColor, borderRadius: BorderRadius.circular(5)), child: Center( child: Text( '${progres[0].totalProgress}%', // '${progressWidth}%', style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth( 12), fontWeight: reguler, color: Colors.white, letterSpacing: 0.5, ), ), ))), ) : Padding( padding: EdgeInsets.only( left: progressWidth - getProportionateScreenWidth(5), // : progressWidth > 390 // ? progressWidth - 25 // : progressWidth - 10, ), child: Container( width: getProportionateScreenWidth(35), height: getProportionateScreenHeight(15), // padding: EdgeInsets.only(left: progressWidth - 5), decoration: BoxDecoration( color: primaryColor, borderRadius: BorderRadius.circular(5)), child: Center( child: Text( '${progres[0].totalProgress}%', style: primaryTextStyle.copyWith( fontSize: getProportionateScreenWidth(12), fontWeight: reguler, color: Colors.white, letterSpacing: 0.5, ), ), ))); }, ), SizedBox( height: getProportionateScreenWidth(5), ), Consumer( builder: (context, state, _) { var progres = state.result!.data[0] .map((e) => e) .where( (element) => element.courseId == lesonOper .map((e) => e.courseId ?? '') .toList() .first, ) .toList(); // print(progres[0]); double progressWidth = (SizeConfig.screenWidth - getProportionateScreenWidth(20)) * int.parse(progres[0].totalProgress.toString()) / 100; return Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(10)), child: Stack( children: [ Container( width: double.infinity, height: getProportionateScreenWidth(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey[300], ), ), Container( width: progressWidth, height: getProportionateScreenWidth(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: primaryColor, ), ), ], ), ); }, ), SizedBox(height: getProportionateScreenHeight(24)), Padding( padding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(10)), child: TabBar( isScrollable: true, padding: EdgeInsets.zero, unselectedLabelColor: Theme.of(context).colorScheme.onBackground, labelColor: primaryColor, indicatorColor: primaryColor, controller: _tabController, labelPadding: EdgeInsets.symmetric( horizontal: getProportionateScreenWidth(20)), tabAlignment: TabAlignment.start, labelStyle: TextStyle(fontWeight: FontWeight.bold), tabs: [ _getTab(0, 'Konten'), _getTab(1, 'Detail'), _getTab(2, 'Q & A'), _getTab(3, 'Pengumuman'), ], ), ), ], ), ), // Container( // width: double.infinity, // height: 1, // decoration: BoxDecoration(boxShadow: [ // BoxShadow( // blurRadius: 5, spreadRadius: 0.1, offset: Offset(0, 10)) // ]), // ), Expanded( child: TabBarView( // physics: NeverScrollableScrollPhysics(), controller: _tabController, children: [ Column( children: [ SizedBox( height: getProportionateScreenHeight(15), ), SizedBox( height: getProportionateScreenHeight(5), ), Expanded( child: ListView.builder( itemCount: sectionOper.length, itemBuilder: (context, index) { final tileKey = GlobalKey(); _tileKeys.add(tileKey); var e = sectionOper.toList()[index]; return Theme( data: ThemeData.dark().copyWith( colorScheme: ColorScheme.dark(primary: secondaryColor), dividerColor: Colors.transparent, ), child: Container( margin: EdgeInsets.only(bottom: 5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10)), child: Column( children: [ tileKursus( tileKey, index, lesonOper, sectionOper, e, lessonMapIdoper, dataLessonOper) ], ), ), ); }), ), ], ), DetailPlayCourse(), QuestAndAnswer( id: lesonOper.map((e) => e.courseId ?? '').toList().first, idLesson: lesonOper.map((e) => e.lessonId ?? '').toList().first, ), Announcement( id: lesonOper.map((e) => e.courseId ?? '').toList().first, lesonOper: lesonOper, sectionOper: sectionOper, lessonMapIdoper: lessonMapIdoper, dataLessonOper: dataLessonOper, ), ], ), ) ], ), ); } return Container( color: Colors.black, child: SafeArea( child: Scaffold( backgroundColor: Theme.of(context).colorScheme.background, key: globalScaffoldKey, body: Consumer( builder: (context, state, _) { if (state.state == ResultState.loading) { return const Center( child: CircularProgressIndicator( strokeWidth: 2, color: primaryColor, ), ); } else if (state.state == ResultState.hasData) { var leson = state.result!.data[0]; var section = state.sectionResult!.data[0].values; section.forEach((element) => element.dataLesson! .forEach((element) => dataLesson.add(element))); List _listVideoUrl = dataLesson .map((e) => YoutubePlayer.convertUrlToId(e.videoUrl ?? '') ?? '') .where((element) => element.isNotEmpty) .toList(); Map lessonMapId = Map.fromIterable(dataLesson, key: (e) => YoutubePlayer.convertUrlToId(e.videoUrl ?? ''), value: (e) => e.lessonId) ..removeWhere((key, value) => key == null || value == null); _isPlayerReady = true; return Column( children: [ if (_isvideoClicked == false) AspectRatio( aspectRatio: 16 / 9, child: Container( width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), image: DecorationImage( fit: BoxFit.fill, image: NetworkImage(widget.thumbnail), ), ), ), ) else if (_isvideoClicked == true && _isyt == true) PiPSwitcher( childWhenEnabled: YoutubePlayerBuilder( player: YoutubePlayer( controller: _controller, ), builder: (p0, p1) { return YoutubePlayer( thumbnail: Container( decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fill, image: NetworkImage(widget.thumbnail), ), ), ), showVideoProgressIndicator: true, progressColors: const ProgressBarColors( handleColor: primaryColor, bufferedColor: Colors.white24, playedColor: primaryColor, backgroundColor: Colors.white24, ), progressIndicatorColor: primaryColor, topActions: [ GestureDetector( onTap: () {}, child: Icon(Icons.expand_more), ), Spacer(), Switch( inactiveThumbImage: AssetImage('assets/images/switch.png'), activeColor: tenthColor, value: state.switchbutton, onChanged: (s) { state.autoplay(); }, ), ], onEnded: (state.switchbutton) ? (data) async { print('masuk sini'); await state.updateLessonCourse( leson .map((e) => e.courseId ?? '') .toList() .first, lessonMapId[ '${playVideoCourseProvider.url}'], ); setState(() async { dataLesson .map((e) => e) .where((element) => element.lessonId == lessonMapId[ '${playVideoCourseProvider.url}']) .first .isFinished = 1; }); await Provider.of< myCourseProvider.MyCourseProvider>( context, listen: false, ).getMyCourse().then((value) => _controller.load( _listVideoUrl[ (_listVideoUrl.indexOf( data.videoId) + 1) % _listVideoUrl.length], )); playVideoCourseProvider.indexUri( _listVideoUrl[(_listVideoUrl .indexOf(data.videoId) + 1) % _listVideoUrl.length], ); } : (d) async { //todo await state.updateLessonCourse( leson .map((e) => e.courseId ?? '') .toList() .first, lessonMapId[ '${playVideoCourseProvider.url}'], ); await Provider.of< myCourseProvider.MyCourseProvider>( context, listen: false, ).getMyCourse(); setState(() { print('KELARR DISINIII'); _gabisaskip = false; dataLesson .map((e) => e) .where((element) => element.lessonId == lessonMapId[ '${playVideoCourseProvider.url}']) .first .isFinished = 1; }); // print('g masuk'); }, onReady: () { _controller.load( YoutubePlayer.convertUrlToId( _listVideoUrl.first) ?? '', ); _isPlayerReady = true; playVideoCourseProvider.uri = _listVideoUrl.first; }, controller: _controller, ); }, ), childWhenDisabled: YoutubePlayerBuilder( player: YoutubePlayer( controller: _controller, ), builder: (p0, p1) { return YoutubePlayer( thumbnail: Container( decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fill, image: NetworkImage(widget.thumbnail), ), ), ), showVideoProgressIndicator: true, progressColors: const ProgressBarColors( handleColor: primaryColor, bufferedColor: Colors.white24, playedColor: primaryColor, backgroundColor: Colors.white24, ), progressIndicatorColor: primaryColor, topActions: [ GestureDetector( onTap: () {}, child: Icon(Icons.expand_more), ), Spacer(), Switch( inactiveThumbImage: AssetImage('assets/images/switch.png'), activeColor: tenthColor, value: state.switchbutton, onChanged: (s) { state.autoplay(); }, ), Padding( padding: EdgeInsets.only(left: 5), child: GestureDetector( onTap: enablePip, child: Icon(Icons.picture_in_picture), ), ) ], onEnded: (state.switchbutton) ? (data) async { print('masuk sini'); await state.updateLessonCourse( leson .map((e) => e.courseId ?? '') .toList() .first, lessonMapId[ '${playVideoCourseProvider.url}'], ); setState(() async { dataLesson .map((e) => e) .where((element) => element.lessonId == lessonMapId[ '${playVideoCourseProvider.url}']) .first .isFinished = 1; }); await Provider.of< myCourseProvider.MyCourseProvider>( context, listen: false, ).getMyCourse().then((value) => _controller.load( _listVideoUrl[ (_listVideoUrl.indexOf( data.videoId) + 1) % _listVideoUrl.length], )); playVideoCourseProvider.indexUri( _listVideoUrl[(_listVideoUrl .indexOf(data.videoId) + 1) % _listVideoUrl.length], ); } : (d) async { //todo await state.updateLessonCourse( leson .map((e) => e.courseId ?? '') .toList() .first, lessonMapId[ '${playVideoCourseProvider.url}'], ); await Provider.of< myCourseProvider.MyCourseProvider>( context, listen: false, ).getMyCourse(); setState(() { print('KELARR DISINIII'); _gabisaskip = false; dataLesson .map((e) => e) .where((element) => element.lessonId == lessonMapId[ '${playVideoCourseProvider.url}']) .first .isFinished = 1; }); // print('g masuk'); }, onReady: () { _controller.load( YoutubePlayer.convertUrlToId( _listVideoUrl.first) ?? '', ); _isPlayerReady = true; playVideoCourseProvider.uri = _listVideoUrl.first; }, controller: _controller, ); }, )) else if (_isvideoClicked == true && _chewieController == '') CircularProgressIndicator() else if (_isvideoClicked == true && _isyt == false) PiPSwitcher( childWhenEnabled: AspectRatio( aspectRatio: 16 / 9, child: Chewie(controller: _chewieController), ), childWhenDisabled: AspectRatio( aspectRatio: 16 / 9, child: Chewie(controller: _chewieController), ), ), Flexible( child: tabbarbawah( context, leson, section, lessonMapId, dataLesson), ) ], ); } else if (state.state == ResultState.error) { Future.delayed(Duration.zero, () { Navigator.pop(context); CherryToast.error( animationDuration: Durations.long1, title: Text("Kursus tidak memiliki materi pembelajaran", style: TextStyle( color: Colors.black, fontSize: 15, )), animationType: AnimationType.fromTop, ).show(context); }); return Center( child: Column( children: [ Text( '', style: thirdTextStyle, ), ], )); } else { return Center( child: Text( 'Terjadi kesalahan', style: thirdTextStyle, ), ); } }, ), ), ), ); } }