Merge branch 'refactor-exercise-provider' into 'master'

Fix: Correct matching pairs answer formatting in review mode and refactor...

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!23
This commit is contained in:
Naresh Pratista 2024-12-04 09:54:23 +00:00
commit 6c265fec33
4 changed files with 154 additions and 82 deletions

View File

@ -1,5 +1,3 @@
const String baseUrl =
'https://ba47-2001-448a-50a0-14bf-701c-6eb0-9412-6ff4.ngrok-free.app/';
const String baseUrl = 'https://c519-114-6-25-184.ngrok-free.app/';
const String mediaUrl =
'https://ba47-2001-448a-50a0-14bf-701c-6eb0-9412-6ff4.ngrok-free.app/api/uploads/';
const String mediaUrl = 'https://c519-114-6-25-184.ngrok-free.app/api/uploads/';

View File

@ -426,8 +426,8 @@ class ExerciseProvider extends ChangeNotifier {
return exercise.answerStudent == '1' ? 'True' : 'False';
case 'MPQ':
if (exercise.answerStudent.isEmpty) return '';
return exercise.answerStudent.split(', ').map((pair) {
final parts = pair.split('-');
return exercise.answerStudent.split('| ').map((pair) {
final parts = pair.split('>');
if (parts.length == 2) {
return '${parts[0]}${parts[1]}';
}
@ -462,6 +462,10 @@ class ExerciseProvider extends ChangeNotifier {
formattedAnswer = formattedAnswer;
} else if (exercise.choices is TrueFalse) {
formattedAnswer = formattedAnswer.toLowerCase() == 'true' ? '1' : '0';
} else if (exercise.choices is MatchingPair) {
// Change '-' to '>' and ', ' to '|'
formattedAnswer =
formattedAnswer.replaceAll('-', '>').replaceAll(', ', '|');
}
return {

View File

@ -6,6 +6,7 @@ import 'package:english_learning/features/learning/modules/exercises/widgets/exe
import 'package:english_learning/features/learning/modules/exercises/widgets/instruction_dialog.dart';
import 'package:flutter/material.dart';
import 'package:english_learning/core/utils/styles/theme.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
class ExerciseScreen extends StatefulWidget {
@ -34,6 +35,17 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
void initState() {
super.initState();
_scrollController = ScrollController();
// Nonaktifkan tombol back pada Android
SystemChannels.platform.setMethodCallHandler((call) async {
if (call.method == 'hardwareKeyboardEvent') {
// Cek apakah tombol back ditekan
if (call.arguments['keyCode'] == 4) {
// 4 adalah kode tombol back di Android
return true; // Mencegah default back behavior
}
}
return false;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = context.read<ExerciseProvider>();
provider.fetchExercises(widget.levelId!);
@ -44,6 +56,7 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
@override
void dispose() {
_scrollController.dispose();
SystemChannels.platform.setMethodCallHandler(null);
super.dispose();
}
@ -57,7 +70,19 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
@override
Widget build(BuildContext context) {
return Consumer<ExerciseProvider>(builder: (context, provider, child) {
return PopScope(
canPop: false, // Prevent default pop behavior
onPopInvokedWithResult: (didPop, result) async {
if (didPop) return;
// Show exit confirmation dialog
final shouldPop = await _showExitConfirmationDialog() ?? false;
if (shouldPop) {
Navigator.of(context).pop();
}
},
child: Consumer<ExerciseProvider>(builder: (context, provider, child) {
if (provider.isLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
@ -139,7 +164,49 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
),
),
);
});
}),
);
}
// Metode untuk menampilkan dialog konfirmasi keluar
Future<bool?> _showExitConfirmationDialog() async {
return showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
backgroundColor: AppColors.whiteColor,
title: Text(
'Exit Exercise',
style: AppTextStyles.blackTextStyle
.copyWith(fontWeight: FontWeight.bold),
),
content: Text(
'Are you sure you want to exit? Your progress will be lost.',
style: AppTextStyles.blackTextStyle,
),
actions: [
TextButton(
onPressed: () =>
Navigator.of(context).pop(false), // Tetap di halaman
child: Text(
'Cancel',
style: AppTextStyles.greyTextStyle,
),
),
ElevatedButton(
onPressed: () {
// Kembali ke halaman sebelumnya
Navigator.of(context).pop(true);
},
style:
ElevatedButton.styleFrom(backgroundColor: AppColors.redColor),
child: Text(
'Exit',
style: AppTextStyles.whiteTextStyle,
),
),
],
),
);
}
void _showInstructions(BuildContext context) {

View File

@ -152,10 +152,13 @@ class _MatchingPairsQuestionState extends State<MatchingPairsQuestion> {
// Rekonstruksi jawaban siswa
if (widget.exercise.answerStudent.isNotEmpty) {
final answerPairs = widget.exercise.answerStudent.split(', ');
studentAnswers = {
for (var pair in answerPairs) pair.split('-')[0]: pair.split('-')[1]
};
final answerPairs = widget.exercise.answerStudent.split('|');
for (var pair in answerPairs) {
final parts = pair.split('>');
if (parts.length == 2) {
studentAnswers[parts[0].trim()] = parts[1].trim();
}
}
}
}
}