Files
Vocasia-LMS-Mobile-apps--TA…/lib/screens/course/play_course_page_old.dart

2023 lines
104 KiB
Dart

// 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<PlayCourseOld> createState() => _PlayCoursePageState();
}
class _PlayCoursePageState extends State<PlayCourseOld>
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> 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<String> 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>[
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<myCourseProvider.MyCourseProvider>(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<void> 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<void> 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"<[^>]*>|&nbsp;|&amp;|&quot;",
multiLine: true, caseSensitive: true);
return htmlText.replaceAll(exp, '');
}
resetExpansionTileKeysAndSelectedIndex();
final selectedTitleProvider = Provider.of<SelectedTitleProvider>(context);
PlayVideoCourseProvider playVideoCourseProvider =
Provider.of<PlayVideoCourseProvider>(context);
var dataProgress = Provider.of<myCourseProvider.MyCourseProvider>(context);
// var dataProgress22 = Provider.of<myCourseProvider.MyCourseProvider>(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<myCourseProvider.MyCourseProvider>(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<LessonCourseProvider>(context)
// .updateLessonCourse(courseId, lessonId);
// }
// });
// }
Duration getVideoDuration(String duration) {
int hours = 0;
int minutes = 0;
int seconds = 0;
List<String> 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<String?, dynamic> lessonMapId,
List<DataLesson> 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<myCourseProvider.MyCourseProvider>(
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<Datum> sectionOper,
Datum e,
Map<String?, dynamic> lessonMapIdoper,
List<DataLesson> 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<Datum> sectionOper,
Map<String?, dynamic> lessonMapIdoper,
List<DataLesson> 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<myCourseProvider.MyCourseProvider>(
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<myCourseProvider.MyCourseProvider>(
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<LessonCourseProvider>(
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<String> _listVideoUrl = dataLesson
.map((e) =>
YoutubePlayer.convertUrlToId(e.videoUrl ?? '') ?? '')
.where((element) => element.isNotEmpty)
.toList();
Map<String?, dynamic> 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,
),
);
}
},
),
),
),
);
}
}