fix: adding back limitation
This commit is contained in:
parent
576f5b27ea
commit
0a138793ae
|
@ -14,7 +14,9 @@ class CustomFloatingLoading {
|
|||
color: Colors.black.withValues(alpha: 0.5),
|
||||
),
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -43,15 +43,17 @@ class DetailHistoryView extends GetView<DetailHistoryController> {
|
|||
|
||||
List<Widget> quizListings() {
|
||||
return controller.quizAnswer.questionListings
|
||||
.map((e) => QuizItemWAComponent(
|
||||
index: e.index,
|
||||
isCorrect: e.isCorrect,
|
||||
question: e.question,
|
||||
targetAnswer: e.targetAnswer,
|
||||
timeSpent: e.timeSpent,
|
||||
type: e.type,
|
||||
userAnswer: e.userAnswer,
|
||||
options: e.options,
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => QuizItemWAComponent(
|
||||
index: entry.key + 1,
|
||||
isCorrect: entry.value.isCorrect,
|
||||
question: entry.value.question,
|
||||
targetAnswer: entry.value.targetAnswer,
|
||||
timeSpent: entry.value.timeSpent,
|
||||
type: entry.value.type,
|
||||
userAnswer: entry.value.userAnswer,
|
||||
options: entry.value.options,
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ class JoinRoomController extends GetxController {
|
|||
);
|
||||
|
||||
final TextEditingController codeController = TextEditingController();
|
||||
RxBool isLoading = false.obs;
|
||||
|
||||
void joinRoom(BuildContext context) {
|
||||
if (!_connectionService.isCurrentlyConnected) {
|
||||
|
@ -42,12 +43,14 @@ class JoinRoomController extends GetxController {
|
|||
return;
|
||||
}
|
||||
CustomFloatingLoading.showLoading(Get.overlayContext!);
|
||||
isLoading.value = true;
|
||||
_socketService.initSocketConnection();
|
||||
|
||||
_socketService.joinRoom(sessionCode: code, userId: _userController.userData!.id);
|
||||
_socketService.errors.listen((error) {
|
||||
CustomNotification.error(title: "not found", message: "Ruangan tidak ditemukan");
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
});
|
||||
|
||||
_socketService.roomMessages.listen((data) {
|
||||
|
@ -57,6 +60,7 @@ class JoinRoomController extends GetxController {
|
|||
final Map<String, dynamic> quizInfoJson = dataPayload["quiz_info"];
|
||||
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
Get.toNamed(
|
||||
AppRoutes.waitRoomPage,
|
||||
arguments: WaitingRoomDTO(
|
||||
|
@ -73,6 +77,10 @@ class JoinRoomController extends GetxController {
|
|||
});
|
||||
}
|
||||
|
||||
void onGoBack() {
|
||||
if (!isLoading.value) Get.back();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
codeController.dispose();
|
||||
|
|
|
@ -12,7 +12,10 @@ class JoinRoomView extends GetView<JoinRoomController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => controller.onGoBack(),
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: AppBar(
|
||||
|
@ -195,6 +198,7 @@ class JoinRoomView extends GetView<JoinRoomController> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,10 +102,12 @@ class LoginController extends GetxController {
|
|||
_userController.setUserFromEntity(userEntity);
|
||||
_userStorageService.isLogged = true;
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
} catch (e, stackTrace) {
|
||||
logC.e(e, stackTrace: stackTrace);
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
CustomNotification.error(title: "Gagal", message: "Periksa kembali email dan kata sandi Anda");
|
||||
}
|
||||
}
|
||||
|
@ -117,11 +119,13 @@ class LoginController extends GetxController {
|
|||
}
|
||||
try {
|
||||
CustomFloatingLoading.showLoading(Get.overlayContext!);
|
||||
isLoading.value = true;
|
||||
final user = await _googleAuthService.signIn();
|
||||
if (user == null) {
|
||||
Get.snackbar("Kesalahan", "Masuk dengan Google dibatalkan");
|
||||
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,6 +134,7 @@ class LoginController extends GetxController {
|
|||
Get.snackbar("Kesalahan", "Tidak menerima ID Token dari Google");
|
||||
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -140,13 +145,20 @@ class LoginController extends GetxController {
|
|||
_userController.setUserFromEntity(userEntity);
|
||||
_userStorageService.isLogged = true;
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
} catch (e, stackTrace) {
|
||||
logC.e("Google Sign-In Error: $e", stackTrace: stackTrace);
|
||||
Get.snackbar("Error", "Google sign-in error");
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
void onGoBack() {
|
||||
if (!isLoading.value) Get.back();
|
||||
}
|
||||
|
||||
void goToRegsPage() => Get.toNamed(AppRoutes.registerPage);
|
||||
|
||||
UserEntity _convertLoginResponseToUserEntity(LoginResponseModel response) {
|
||||
|
|
|
@ -15,7 +15,10 @@ class LoginView extends GetView<LoginController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => controller.onGoBack(),
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
|
@ -82,6 +85,7 @@ class LoginView extends GetView<LoginController> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ class ProfileController extends GetxController {
|
|||
birthDate.value = _userController.userData?.birthDate ?? "";
|
||||
phoneNumber.value = _userController.userData?.phone ?? "";
|
||||
joinDate.value = _userController.userData?.createdAt ?? "";
|
||||
|
||||
} catch (e, stackTrace) {
|
||||
logC.e("Failed to load user profile data: $e", stackTrace: stackTrace);
|
||||
}
|
||||
|
@ -114,9 +113,9 @@ class ProfileController extends GetxController {
|
|||
}
|
||||
|
||||
void editProfile() async {
|
||||
final bool resultUpdate = await Get.toNamed(AppRoutes.updateProfilePage);
|
||||
final resultUpdate = await Get.toNamed(AppRoutes.updateProfilePage);
|
||||
|
||||
if (resultUpdate) {
|
||||
if (resultUpdate == true) {
|
||||
loadUserProfileData();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ class UpdateProfileController extends GetxController {
|
|||
|
||||
var selectedLocale = 'en-US'.obs;
|
||||
|
||||
RxBool isLoading = false.obs;
|
||||
|
||||
final Map<String, String> localeMap = {
|
||||
'English': 'en-US',
|
||||
'Indonesian': 'id-ID',
|
||||
|
@ -78,6 +80,7 @@ class UpdateProfileController extends GetxController {
|
|||
|
||||
try {
|
||||
CustomFloatingLoading.showLoading(Get.overlayContext!);
|
||||
isLoading.value = true;
|
||||
final isSuccessUpdate = await _userService.updateProfileData(
|
||||
_userController.userData!.id,
|
||||
nameController.text.trim(),
|
||||
|
@ -111,11 +114,13 @@ class UpdateProfileController extends GetxController {
|
|||
}
|
||||
}
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
|
||||
Get.back(result: true);
|
||||
CustomNotification.success(title: "Success", message: "Profile updated successfully");
|
||||
} catch (e) {
|
||||
CustomNotification.success(title: "something wrong", message: "failed to update profile");
|
||||
isLoading.value = false;
|
||||
logC.e(e);
|
||||
}
|
||||
}
|
||||
|
@ -124,4 +129,8 @@ class UpdateProfileController extends GetxController {
|
|||
final regex = RegExp(r'^([0-2][0-9]|(3)[0-1])\-((0[1-9])|(1[0-2]))\-\d{4}$');
|
||||
return regex.hasMatch(date);
|
||||
}
|
||||
|
||||
void onGoBack() {
|
||||
if (!isLoading.value) Get.back();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@ import 'package:quiz_app/feature/profile/controller/update_profile_controller.da
|
|||
class UpdateProfilePage extends GetView<UpdateProfileController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => controller.onGoBack(),
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background2,
|
||||
appBar: AppBar(
|
||||
backgroundColor: AppColors.background2,
|
||||
|
@ -65,6 +68,7 @@ class UpdateProfilePage extends GetView<UpdateProfileController> {
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ class QuizCreationController extends GetxController {
|
|||
|
||||
RxInt currentDuration = 30.obs;
|
||||
|
||||
RxBool isLoading = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
@ -199,7 +201,7 @@ class QuizCreationController extends GetxController {
|
|||
|
||||
void onBack(BuildContext context) {
|
||||
if (quizData.length <= 1) {
|
||||
Navigator.pop(context);
|
||||
Get.back();
|
||||
} else {
|
||||
AppDialog.showExitConfirmationDialog(context);
|
||||
}
|
||||
|
@ -240,50 +242,67 @@ class QuizCreationController extends GetxController {
|
|||
return;
|
||||
}
|
||||
CustomFloatingLoading.showLoading(Get.overlayContext!);
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
BaseResponseModel<List<RawQuizModel>> response = await _quizService.createQuizAuto(inputSentenceTC.text);
|
||||
|
||||
if (response.data != null) {
|
||||
final previousLength = quizData.length;
|
||||
if (response.data != null && response.data!.isNotEmpty) {
|
||||
// Check if we should remove the initial empty question
|
||||
bool shouldRemoveInitial = quizData.length == 1 && quizData[0].question == null && quizData[0].answer == null;
|
||||
|
||||
if (previousLength == 1) quizData.removeAt(0);
|
||||
if (shouldRemoveInitial) {
|
||||
quizData.clear();
|
||||
}
|
||||
|
||||
for (final i in response.data!) {
|
||||
// Add new questions
|
||||
for (final quizItem in response.data!) {
|
||||
QuestionType type = QuestionType.fillTheBlank;
|
||||
|
||||
if (i.answer.toString().toLowerCase() == 'true' || i.answer.toString().toLowerCase() == 'false') {
|
||||
if (quizItem.answer.toString().toLowerCase() == 'true' || quizItem.answer.toString().toLowerCase() == 'false') {
|
||||
type = QuestionType.trueOrFalse;
|
||||
}
|
||||
|
||||
quizData.add(QuestionData(
|
||||
index: quizData.length + 1,
|
||||
question: i.qustion,
|
||||
answer: i.answer,
|
||||
question: quizItem.qustion,
|
||||
answer: quizItem.answer,
|
||||
type: type,
|
||||
));
|
||||
}
|
||||
|
||||
if (response.data!.isNotEmpty) {
|
||||
selectedQuizIndex.value = previousLength;
|
||||
// Set the selected index to the first newly added question
|
||||
if (shouldRemoveInitial) {
|
||||
selectedQuizIndex.value = 0;
|
||||
} else {
|
||||
// If we didn't remove initial data, select the first new question
|
||||
selectedQuizIndex.value = quizData.length - response.data!.length;
|
||||
}
|
||||
|
||||
// Update UI with the selected question data
|
||||
if (selectedQuizIndex.value < quizData.length) {
|
||||
final data = quizData[selectedQuizIndex.value];
|
||||
questionTC.text = data.question ?? "";
|
||||
answerTC.text = data.answer ?? "";
|
||||
currentDuration.value = data.duration;
|
||||
currentQuestionType.value = data.type ?? QuestionType.fillTheBlank;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logC.e("Error while generating quiz: $e");
|
||||
CustomFloatingLoading.hideLoading();
|
||||
} finally {
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
isGenerate.value = false;
|
||||
|
||||
inputSentenceTC.text = "";
|
||||
|
||||
if (quizData.isNotEmpty && selectedQuizIndex.value == 0) {
|
||||
final data = quizData[0];
|
||||
if (quizData.isNotEmpty && selectedQuizIndex.value >= quizData.length) {
|
||||
selectedQuizIndex.value = 0;
|
||||
}
|
||||
|
||||
if (quizData.isNotEmpty) {
|
||||
final data = quizData[selectedQuizIndex.value];
|
||||
questionTC.text = data.question ?? "";
|
||||
answerTC.text = data.answer ?? "";
|
||||
currentDuration.value = data.duration;
|
||||
|
@ -291,4 +310,8 @@ class QuizCreationController extends GetxController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
onGoBack(BuildContext context, bool didPop) {
|
||||
if (!isLoading.value) onBack(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@ class QuizCreationView extends GetView<QuizCreationController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => controller.onGoBack(context, didPop),
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor: AppColors.background,
|
||||
|
@ -44,6 +47,7 @@ class QuizCreationView extends GetView<QuizCreationController> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,10 @@ class QuizPreviewController extends GetxController {
|
|||
subjectIndex.value = index;
|
||||
}
|
||||
|
||||
void onBack() {
|
||||
if (!isLoading.value) Get.back();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
titleController.dispose();
|
||||
|
|
|
@ -34,6 +34,7 @@ class SubjectDropdownComponent extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
},
|
||||
dropdownColor: Colors.white,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
|
|
|
@ -14,7 +14,10 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => controller.onBack(),
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
appBar: _buildAppBar(context),
|
||||
body: SafeArea(
|
||||
|
@ -23,6 +26,7 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
|||
child: _buildContent(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ class RegisterController extends GetxController {
|
|||
var isPasswordHidden = true.obs;
|
||||
var isConfirmPasswordHidden = true.obs;
|
||||
|
||||
RxBool isLoading = false.obs;
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
if (!_connectionService.isCurrentlyConnected) {
|
||||
|
@ -82,6 +84,7 @@ class RegisterController extends GetxController {
|
|||
|
||||
try {
|
||||
CustomFloatingLoading.showLoading(Get.overlayContext!);
|
||||
isLoading.value = true;
|
||||
await _authService.register(
|
||||
RegisterRequestModel(
|
||||
email: email,
|
||||
|
@ -94,9 +97,11 @@ class RegisterController extends GetxController {
|
|||
|
||||
Get.back();
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
CustomNotification.success(title: "Pendaftaran Berhasil", message: "Akun berhasil dibuat");
|
||||
} catch (e) {
|
||||
CustomFloatingLoading.hideLoading();
|
||||
isLoading.value = false;
|
||||
|
||||
String errorMessage = e.toString().replaceFirst("Exception: ", "");
|
||||
|
||||
|
|
Loading…
Reference in New Issue