2076 lines
106 KiB
Dart
2076 lines
106 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/current_lesson_provider.dart';
|
|
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 PlayCourse extends StatefulWidget {
|
|
const PlayCourse(
|
|
{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<PlayCourse> createState() => _PlayCoursePageState();
|
|
}
|
|
|
|
class _PlayCoursePageState extends State<PlayCourse>
|
|
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
|
|
late TabController _tabController;
|
|
LessonCourseService lessonCourseService = LessonCourseService();
|
|
|
|
late YoutubePlayerController _controller;
|
|
|
|
late PlayerState _playerState;
|
|
late YoutubeMetaData _videoMetaData;
|
|
|
|
Duration _currentTime = const Duration();
|
|
String? _setLocalLEssonId = "";
|
|
int _ytCurrentTime = 0;
|
|
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);
|
|
print(
|
|
"----------------------------------------------------------------> setup");
|
|
_controller = YoutubePlayerController(
|
|
//todo
|
|
initialVideoId: "",
|
|
flags: const YoutubePlayerFlags(
|
|
mute: false,
|
|
disableDragSeek: false,
|
|
loop: false,
|
|
isLive: false,
|
|
forceHD: false,
|
|
enableCaption: false,
|
|
autoPlay: true,
|
|
hideThumbnail: true,
|
|
startAt: 0,
|
|
),
|
|
)..addListener(() {
|
|
setState(() {
|
|
_playerState = _controller.value.playerState;
|
|
_currentTime = _controller.value.position;
|
|
});
|
|
|
|
if (_playerState == PlayerState.paused) {
|
|
() async {
|
|
await LessonCourseService().updateLessonCourse(_setLocalLEssonId,
|
|
progress: _currentTime.inSeconds);
|
|
}();
|
|
}
|
|
|
|
print(
|
|
"INI Current TIME --------------------------------->$_currentTime");
|
|
});
|
|
_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() {
|
|
_controller.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) {
|
|
CurrentLessonProvider currentLesson =
|
|
Provider.of<CurrentLessonProvider>(context, listen: false);
|
|
|
|
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<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')
|
|
? () {
|
|
setState(() {
|
|
_ytCurrentTime =
|
|
double.parse(e.value.progress ?? '0')
|
|
.round();
|
|
_isvideoClicked = true;
|
|
_isPlayerReady = true;
|
|
_setLocalLEssonId = e.value.lessonId;
|
|
});
|
|
print('masuk sini $_ytCurrentTime');
|
|
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 {
|
|
print(
|
|
"MASUK SINI KAH?? ---------------------> $_ytCurrentTime");
|
|
print(
|
|
"link ------------------------------------------------>${YoutubePlayer.convertUrlToId(playVideoCourseProvider.url)!}");
|
|
_controller.load(
|
|
YoutubePlayer.convertUrlToId(
|
|
playVideoCourseProvider.url)!,
|
|
startAt: _ytCurrentTime,
|
|
);
|
|
_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) ??
|
|
'',
|
|
startAt: _ytCurrentTime,
|
|
);
|
|
_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) ??
|
|
'',
|
|
startAt: _ytCurrentTime,
|
|
);
|
|
_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))
|
|
// ]),
|
|
// ),
|
|
SizedBox(
|
|
height: 500,
|
|
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 SingleChildScrollView(
|
|
child: 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),
|
|
),
|
|
),
|
|
|
|
tabbarbawah(
|
|
context, leson, section, lessonMapId, dataLesson),
|
|
|
|
// 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,
|
|
),
|
|
);
|
|
}
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|