feat: adding limitation on the join and create room
This commit is contained in:
parent
ede385041e
commit
d5de5fb712
|
@ -1,6 +1,6 @@
|
|||
class APIEndpoint {
|
||||
static const String baseUrl = "http://192.168.1.18:5000";
|
||||
// static const String baseUrl = "http://103.193.178.121:5000";
|
||||
// static const String baseUrl = "http://192.168.107.43:5000";
|
||||
static const String baseUrl = "http://103.193.178.121:5000";
|
||||
static const String api = "$baseUrl/api";
|
||||
|
||||
static const String login = "/login";
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class CustomFloatingLoading {
|
||||
static void showLoadingDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
barrierColor: Colors.black.withValues(alpha: 0.3),
|
||||
builder: (BuildContext context) {
|
||||
return PopScope(
|
||||
static const String _dialogId = 'custom_loading';
|
||||
|
||||
static void showLoadingDialog() {
|
||||
Get.dialog(
|
||||
PopScope(
|
||||
canPop: false,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
child: const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
);
|
||||
},
|
||||
barrierDismissible: false,
|
||||
barrierColor: Colors.black.withAlpha(76),
|
||||
name: _dialogId,
|
||||
);
|
||||
}
|
||||
|
||||
static void hideLoadingDialog(BuildContext context) {
|
||||
Navigator.of(context).pop();
|
||||
static void hideLoadingDialog() {
|
||||
if (Get.isOverlaysOpen) {
|
||||
Get.until((route) => route.settings.name != _dialogId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class ConnectionService extends GetxService {
|
|||
isConnected.value = results.any((result) => result != ConnectivityResult.none);
|
||||
}
|
||||
|
||||
Future<bool> checkConnection() async {
|
||||
Future<bool> isHaveConnection() async {
|
||||
final result = await _connectivity.checkConnectivity();
|
||||
return !result.contains(ConnectivityResult.none);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||
import 'package:quiz_app/data/services/connection_service.dart';
|
||||
import 'package:quiz_app/data/services/socket_service.dart';
|
||||
import 'package:quiz_app/feature/join_room/controller/join_room_controller.dart';
|
||||
|
||||
|
@ -8,6 +9,12 @@ class JoinRoomBinding extends Bindings {
|
|||
void dependencies() {
|
||||
Get.put(SocketService());
|
||||
|
||||
Get.lazyPut(() => JoinRoomController(Get.find<SocketService>(), Get.find<UserController>()));
|
||||
Get.lazyPut(
|
||||
() => JoinRoomController(
|
||||
Get.find<SocketService>(),
|
||||
Get.find<UserController>(),
|
||||
Get.find<ConnectionService>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/core/helper/connection_check.dart';
|
||||
import 'package:quiz_app/core/utils/custom_floating_loading.dart';
|
||||
import 'package:quiz_app/core/utils/custom_notification.dart';
|
||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||
import 'package:quiz_app/data/dto/waiting_room_dto.dart';
|
||||
import 'package:quiz_app/data/models/quiz/quiz_info_model.dart';
|
||||
import 'package:quiz_app/data/models/session/session_info_model.dart';
|
||||
import 'package:quiz_app/data/models/session/session_response_model.dart';
|
||||
import 'package:quiz_app/data/services/connection_service.dart';
|
||||
import 'package:quiz_app/data/services/socket_service.dart';
|
||||
|
||||
class JoinRoomController extends GetxController {
|
||||
final SocketService _socketService;
|
||||
final UserController _userController;
|
||||
final ConnectionService _connectionService;
|
||||
|
||||
JoinRoomController(this._socketService, this._userController);
|
||||
JoinRoomController(
|
||||
this._socketService,
|
||||
this._userController,
|
||||
this._connectionService,
|
||||
);
|
||||
|
||||
final TextEditingController codeController = TextEditingController();
|
||||
|
||||
void joinRoom() {
|
||||
void joinRoom(BuildContext context) {
|
||||
if (!_connectionService.isCurrentlyConnected) {
|
||||
ConnectionNotification.noInternedConnection();
|
||||
return;
|
||||
}
|
||||
final code = codeController.text.trim();
|
||||
|
||||
if (code.isEmpty) {
|
||||
|
@ -29,18 +41,13 @@ class JoinRoomController extends GetxController {
|
|||
);
|
||||
return;
|
||||
}
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
_socketService.initSocketConnection();
|
||||
|
||||
_socketService.joinRoom(sessionCode: code, userId: _userController.userData!.id);
|
||||
_socketService.errors.listen((error) {
|
||||
Get.snackbar(
|
||||
"not found",
|
||||
"Ruangan tidak ditemukan",
|
||||
backgroundColor: Get.theme.colorScheme.error.withValues(alpha: 0.9),
|
||||
colorText: Colors.white,
|
||||
);
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomNotification.error(title: "not found", message: "Ruangan tidak ditemukan");
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
});
|
||||
|
||||
_socketService.roomMessages.listen((data) {
|
||||
|
@ -49,7 +56,7 @@ class JoinRoomController extends GetxController {
|
|||
final Map<String, dynamic> sessionInfoJson = dataPayload["session_info"];
|
||||
final Map<String, dynamic> quizInfoJson = dataPayload["quiz_info"];
|
||||
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
// CustomFloatingLoading.hideLoadingDialog(context);
|
||||
Get.toNamed(
|
||||
AppRoutes.waitRoomPage,
|
||||
arguments: WaitingRoomDTO(
|
||||
|
|
|
@ -182,7 +182,7 @@ class JoinRoomView extends GetView<JoinRoomController> {
|
|||
const SizedBox(height: 30),
|
||||
GlobalButton(
|
||||
text: context.tr("join_quiz_now"),
|
||||
onPressed: controller.joinRoom,
|
||||
onPressed: () => controller.joinRoom(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -88,7 +88,7 @@ class LoginController extends GetxController {
|
|||
}
|
||||
try {
|
||||
isLoading.value = true;
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
|
||||
final LoginResponseModel response = await _authService.loginWithEmail(
|
||||
LoginRequestModel(email: email, password: password),
|
||||
|
@ -99,11 +99,11 @@ class LoginController extends GetxController {
|
|||
await _userStorageService.saveUser(userEntity);
|
||||
_userController.setUserFromEntity(userEntity);
|
||||
_userStorageService.isLogged = true;
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
} catch (e, stackTrace) {
|
||||
logC.e(e, stackTrace: stackTrace);
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
CustomNotification.error(title: "Gagal", message: "Periksa kembali email dan kata sandi Anda");
|
||||
}
|
||||
}
|
||||
|
@ -114,12 +114,12 @@ class LoginController extends GetxController {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
final user = await _googleAuthService.signIn();
|
||||
if (user == null) {
|
||||
Get.snackbar("Kesalahan", "Masuk dengan Google dibatalkan");
|
||||
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ class LoginController extends GetxController {
|
|||
if (idToken == null || idToken.isEmpty) {
|
||||
Get.snackbar("Kesalahan", "Tidak menerima ID Token dari Google");
|
||||
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ class LoginController extends GetxController {
|
|||
await _userStorageService.saveUser(userEntity);
|
||||
_userController.setUserFromEntity(userEntity);
|
||||
_userStorageService.isLogged = true;
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
} catch (e, stackTrace) {
|
||||
logC.e("Google Sign-In Error: $e", stackTrace: stackTrace);
|
||||
|
|
|
@ -61,7 +61,7 @@ class UpdateProfileController extends GetxController {
|
|||
Future<void> saveProfile() async {
|
||||
if (!_validateInputs()) return;
|
||||
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
|
||||
final isSuccessUpdate = await _userService.updateProfileData(
|
||||
_userController.userData!.id,
|
||||
|
@ -98,7 +98,7 @@ class UpdateProfileController extends GetxController {
|
|||
Get.back();
|
||||
|
||||
CustomNotification.success(title: "Success", message: "Profile updated successfully");
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
}
|
||||
|
||||
bool _isValidDateFormat(String date) {
|
||||
|
|
|
@ -224,7 +224,7 @@ class QuizCreationController extends GetxController {
|
|||
}
|
||||
|
||||
void generateQuiz() async {
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
|
||||
try {
|
||||
BaseResponseModel<List<RawQuizModel>> response = await _quizService.createQuizAuto(inputSentenceTC.text);
|
||||
|
@ -262,7 +262,7 @@ class QuizCreationController extends GetxController {
|
|||
} catch (e) {
|
||||
logC.e("Error while generating quiz: $e");
|
||||
} finally {
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
isGenerate.value = false;
|
||||
|
||||
if (quizData.isNotEmpty && selectedQuizIndex.value == 0) {
|
||||
|
|
|
@ -92,7 +92,7 @@ class QuizPreviewController extends GetxController {
|
|||
}
|
||||
|
||||
isLoading.value = true;
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
|
||||
final now = DateTime.now();
|
||||
final String formattedDate = "${now.day.toString().padLeft(2, '0')}-${now.month.toString().padLeft(2, '0')}-${now.year}";
|
||||
|
@ -122,7 +122,7 @@ class QuizPreviewController extends GetxController {
|
|||
logC.e(e);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
// CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
// CustomFloatingLoading.hideLoadingDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class RegisterController extends GetxController {
|
|||
}
|
||||
|
||||
try {
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.showLoadingDialog();
|
||||
await _authService.register(
|
||||
RegisterRequestModel(
|
||||
email: email,
|
||||
|
@ -93,10 +93,10 @@ class RegisterController extends GetxController {
|
|||
);
|
||||
|
||||
Get.back();
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
CustomNotification.success(title: "Pendaftaran Berhasil", message: "Akun berhasil dibuat");
|
||||
} catch (e) {
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
CustomFloatingLoading.hideLoadingDialog();
|
||||
|
||||
String errorMessage = e.toString().replaceFirst("Exception: ", "");
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||
import 'package:quiz_app/data/services/connection_service.dart';
|
||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||
import 'package:quiz_app/data/services/session_service.dart';
|
||||
import 'package:quiz_app/data/services/socket_service.dart';
|
||||
|
@ -16,6 +17,7 @@ class RoomMakerBinding extends Bindings {
|
|||
Get.find<UserController>(),
|
||||
Get.find<SocketService>(),
|
||||
Get.find<QuizService>(),
|
||||
Get.find<ConnectionService>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/core/helper/connection_check.dart';
|
||||
import 'package:quiz_app/core/utils/custom_notification.dart';
|
||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||
import 'package:quiz_app/data/dto/waiting_room_dto.dart';
|
||||
import 'package:quiz_app/data/models/base/base_model.dart';
|
||||
|
@ -9,6 +11,7 @@ import 'package:quiz_app/data/models/quiz/quiz_listing_model.dart';
|
|||
import 'package:quiz_app/data/models/session/session_info_model.dart';
|
||||
import 'package:quiz_app/data/models/session/session_request_model.dart';
|
||||
import 'package:quiz_app/data/models/session/session_response_model.dart';
|
||||
import 'package:quiz_app/data/services/connection_service.dart';
|
||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||
import 'package:quiz_app/data/services/session_service.dart';
|
||||
import 'package:quiz_app/data/services/socket_service.dart';
|
||||
|
@ -18,12 +21,14 @@ class RoomMakerController extends GetxController {
|
|||
final UserController _userController;
|
||||
final SocketService _socketService;
|
||||
final QuizService _quizService;
|
||||
final ConnectionService _connectionService;
|
||||
|
||||
RoomMakerController(
|
||||
this._sessionService,
|
||||
this._userController,
|
||||
this._socketService,
|
||||
this._quizService,
|
||||
this._connectionService,
|
||||
);
|
||||
|
||||
final selectedQuiz = Rxn<QuizListingModel>();
|
||||
|
@ -47,6 +52,10 @@ class RoomMakerController extends GetxController {
|
|||
}
|
||||
|
||||
Future<void> loadQuiz({bool reset = false}) async {
|
||||
if (!await _connectionService.isHaveConnection()) {
|
||||
ConnectionNotification.noInternedConnection();
|
||||
return;
|
||||
}
|
||||
if (isLoading) return;
|
||||
|
||||
isLoading = true;
|
||||
|
@ -92,8 +101,13 @@ class RoomMakerController extends GetxController {
|
|||
}
|
||||
|
||||
void onCreateRoom() async {
|
||||
if (nameTC.text.trim().isEmpty || selectedQuiz.value == null) {
|
||||
Get.snackbar("Gagal", "Nama room dan kuis harus dipilih.");
|
||||
if (nameTC.text.trim().isEmpty || maxPlayerTC.text.trim().isEmpty || selectedQuiz.value == null) {
|
||||
CustomNotification.error(title: "Gagal", message: "Nama room, maksimal pemain dan kuis harus dipilih.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await _connectionService.isHaveConnection()) {
|
||||
ConnectionNotification.noInternedConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -588,27 +588,22 @@ class RoomMakerView extends GetView<RoomMakerController> {
|
|||
}
|
||||
|
||||
Widget _buildCreateRoomButton() {
|
||||
return Obx(() {
|
||||
final canCreate = controller.selectedQuiz.value != null && controller.nameTC.text.isNotEmpty && controller.maxPlayerTC.text.isNotEmpty;
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
width: MediaQuery.of(Get.context!).size.width - 32,
|
||||
height: 56,
|
||||
child: Material(
|
||||
elevation: canCreate ? 8 : 2,
|
||||
elevation: 8,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
onTap: canCreate ? controller.onCreateRoom : null,
|
||||
onTap: controller.onCreateRoom,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: canCreate
|
||||
? LinearGradient(
|
||||
gradient: LinearGradient(
|
||||
colors: [AppColors.primaryBlue, AppColors.primaryBlue.withValues(alpha: 0.8)],
|
||||
)
|
||||
: null,
|
||||
color: !canCreate ? Colors.grey[300] : null,
|
||||
),
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Row(
|
||||
|
@ -616,7 +611,7 @@ class RoomMakerView extends GetView<RoomMakerController> {
|
|||
children: [
|
||||
Icon(
|
||||
Icons.add_circle,
|
||||
color: canCreate ? Colors.white : Colors.grey[500],
|
||||
color: Colors.white,
|
||||
size: 24,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
|
@ -625,7 +620,7 @@ class RoomMakerView extends GetView<RoomMakerController> {
|
|||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: canCreate ? Colors.white : Colors.grey[500],
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -634,6 +629,5 @@ class RoomMakerView extends GetView<RoomMakerController> {
|
|||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue