diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index e815171..1537c4c 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -6,6 +6,8 @@ import 'package:quiz_app/feature/history/view/detail_history_view.dart'; import 'package:quiz_app/feature/home/binding/home_binding.dart'; import 'package:quiz_app/feature/home/view/home_page.dart'; import 'package:quiz_app/feature/detail_quiz/binding/detail_quiz_binding.dart'; +import 'package:quiz_app/feature/join_room/binding/join_room_binding.dart'; +import 'package:quiz_app/feature/join_room/view/join_room_view.dart'; import 'package:quiz_app/feature/library/binding/library_binding.dart'; import 'package:quiz_app/feature/detail_quiz/view/detail_quix_view.dart'; import 'package:quiz_app/feature/listing_quiz/binding/listing_quiz_binding.dart'; @@ -113,6 +115,11 @@ class AppPages { name: AppRoutes.waitRoomPage, page: () => WaitingRoomView(), binding: WaitingRoomBinding(), + ), + GetPage( + name: AppRoutes.joinRoomPage, + page: () => JoinRoomView(), + binding: JoinRoomBinding(), ) ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index bdb3b2b..14a39ee 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -19,5 +19,6 @@ abstract class AppRoutes { static const detailHistoryPage = "/history/detail"; static const roomPage = "/room/quiz"; + static const joinRoomPage = "/room/quiz/join"; static const waitRoomPage = "/room/quiz/waiting"; } diff --git a/lib/feature/home/controller/home_controller.dart b/lib/feature/home/controller/home_controller.dart index 4dff15d..d1e3bec 100644 --- a/lib/feature/home/controller/home_controller.dart +++ b/lib/feature/home/controller/home_controller.dart @@ -52,6 +52,8 @@ class HomeController extends GetxController { void goToRoomMaker() => Get.toNamed(AppRoutes.roomPage); + void goToJoinRoom() => Get.toNamed(AppRoutes.joinRoomPage); + void goToSearch() { final navController = Get.find(); navController.changePage(1); diff --git a/lib/feature/home/view/home_page.dart b/lib/feature/home/view/home_page.dart index 2cbddb6..caab0ec 100644 --- a/lib/feature/home/view/home_page.dart +++ b/lib/feature/home/view/home_page.dart @@ -36,7 +36,7 @@ class HomeView extends GetView { ButtonOption( onCreate: controller.goToQuizCreation, onCreateRoom: controller.goToRoomMaker, - onJoinRoom: () {}, + onJoinRoom: controller.goToJoinRoom, ), Padding( padding: const EdgeInsets.all(20), diff --git a/lib/feature/join_room/binding/join_room_binding.dart b/lib/feature/join_room/binding/join_room_binding.dart new file mode 100644 index 0000000..cde17c8 --- /dev/null +++ b/lib/feature/join_room/binding/join_room_binding.dart @@ -0,0 +1,13 @@ +import 'package:get/get.dart'; +import 'package:quiz_app/data/controllers/user_controller.dart'; +import 'package:quiz_app/data/services/socket_service.dart'; +import 'package:quiz_app/feature/join_room/controller/join_room_controller.dart'; + +class JoinRoomBinding extends Bindings { + @override + void dependencies() { + Get.put(SocketService()); + + Get.lazyPut(() => JoinRoomController(Get.find(), Get.find())); + } +} diff --git a/lib/feature/join_room/controller/join_room_controller.dart b/lib/feature/join_room/controller/join_room_controller.dart new file mode 100644 index 0000000..a92ecf4 --- /dev/null +++ b/lib/feature/join_room/controller/join_room_controller.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:quiz_app/app/routes/app_pages.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/session/session_response_model.dart'; +import 'package:quiz_app/data/services/socket_service.dart'; + +class JoinRoomController extends GetxController { + final SocketService _socketService; + final UserController _userController; + + JoinRoomController(this._socketService, this._userController); + + final TextEditingController codeController = TextEditingController(); + + void joinRoom() { + final code = codeController.text.trim(); + + if (code.isEmpty) { + Get.snackbar( + "Error", + "Kode room dan nama harus diisi", + backgroundColor: Get.theme.colorScheme.error.withOpacity(0.9), + colorText: Colors.white, + ); + return; + } + _socketService.initSocketConnection(); + _socketService.joinRoom(sessionCode: code, userId: _userController.userData!.id); + Get.toNamed(AppRoutes.waitRoomPage, arguments: WaitingRoomDTO(false, SessionResponseModel(sessionId: "", sessionCode: code))); + } + + @override + void onClose() { + codeController.dispose(); + super.onClose(); + } +} diff --git a/lib/feature/join_room/view/join_room_view.dart b/lib/feature/join_room/view/join_room_view.dart new file mode 100644 index 0000000..8e8c860 --- /dev/null +++ b/lib/feature/join_room/view/join_room_view.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:quiz_app/app/const/colors/app_colors.dart'; +import 'package:quiz_app/component/global_button.dart'; +import 'package:quiz_app/component/global_text_field.dart'; +import 'package:quiz_app/feature/join_room/controller/join_room_controller.dart'; + +class JoinRoomView extends GetView { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.background, + appBar: AppBar( + backgroundColor: AppColors.background, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios_new, color: Colors.black87), + onPressed: () => Get.back(), + ), + ), + body: SafeArea( + child: Center( + child: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.06), + blurRadius: 14, + offset: const Offset(0, 6), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "Masukkan Kode Room", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w700, + color: Colors.black87, + ), + ), + const SizedBox(height: 16), + GlobalTextField( + controller: controller.codeController, + hintText: "AB123C", + textInputType: TextInputType.text, + // Uncomment if needed: + // maxLength: 6, + // inputFormatters: [ + // FilteringTextInputFormatter.allow(RegExp(r'[A-Z0-9]')), + // UpperCaseTextFormatter(), + // ], + ), + const SizedBox(height: 30), + GlobalButton( + text: "Gabung Sekarang", + onPressed: controller.joinRoom, + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/feature/room_maker/binding/room_maker_binding.dart b/lib/feature/room_maker/binding/room_maker_binding.dart index f2483c4..65463ed 100644 --- a/lib/feature/room_maker/binding/room_maker_binding.dart +++ b/lib/feature/room_maker/binding/room_maker_binding.dart @@ -1,12 +1,18 @@ import 'package:get/get.dart'; import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/services/session_service.dart'; +import 'package:quiz_app/data/services/socket_service.dart'; import 'package:quiz_app/feature/room_maker/controller/room_maker_controller.dart'; class RoomMakerBinding extends Bindings { @override void dependencies() { Get.lazyPut(() => SessionService()); - Get.lazyPut(() => RoomMakerController(Get.find(), Get.find())); + Get.put(SocketService()); + Get.lazyPut(() => RoomMakerController( + Get.find(), + Get.find(), + Get.find(), + )); } } diff --git a/lib/feature/room_maker/controller/room_maker_controller.dart b/lib/feature/room_maker/controller/room_maker_controller.dart index d77406e..f301fb3 100644 --- a/lib/feature/room_maker/controller/room_maker_controller.dart +++ b/lib/feature/room_maker/controller/room_maker_controller.dart @@ -6,12 +6,18 @@ import 'package:quiz_app/data/dto/waiting_room_dto.dart'; import 'package:quiz_app/data/models/quiz/quiz_listing_model.dart'; import 'package:quiz_app/data/models/session/session_request_model.dart'; import 'package:quiz_app/data/services/session_service.dart'; +import 'package:quiz_app/data/services/socket_service.dart'; class RoomMakerController extends GetxController { final SessionService _sessionService; final UserController _userController; + final SocketService _socketService; - RoomMakerController(this._sessionService, this._userController); + RoomMakerController( + this._sessionService, + this._userController, + this._socketService, + ); // final roomName = ''.obs; final selectedQuiz = Rxn(); @@ -45,7 +51,6 @@ class RoomMakerController extends GetxController { ].obs; void onCreateRoom() async { - print("room ${nameTC.text} || ${selectedQuiz.value}"); if (nameTC.text.trim().isEmpty || selectedQuiz.value == null) { Get.snackbar("Gagal", "Nama room dan kuis harus dipilih."); return; @@ -61,7 +66,12 @@ class RoomMakerController extends GetxController { ), ); - if (response != null) Get.toNamed(AppRoutes.waitRoomPage, arguments: WaitingRoomDTO(true, response.data!)); + if (response != null) { + _socketService.initSocketConnection(); + _socketService.joinRoom(sessionCode: response.data!.sessionCode, userId: _userController.userData!.id); + + Get.toNamed(AppRoutes.waitRoomPage, arguments: WaitingRoomDTO(true, response.data!)); + } } void onQuizSourceChange(bool base) { diff --git a/lib/feature/waiting_room/binding/waiting_room_binding.dart b/lib/feature/waiting_room/binding/waiting_room_binding.dart index d26c263..1fb5fbc 100644 --- a/lib/feature/waiting_room/binding/waiting_room_binding.dart +++ b/lib/feature/waiting_room/binding/waiting_room_binding.dart @@ -6,7 +6,7 @@ import 'package:quiz_app/feature/waiting_room/controller/waiting_room_controller class WaitingRoomBinding extends Bindings { @override void dependencies() { - Get.put(SocketService()); + if (!Get.isRegistered()) Get.put(SocketService()); Get.lazyPut(() => WaitingRoomController( Get.find(), Get.find(), diff --git a/lib/feature/waiting_room/controller/waiting_room_controller.dart b/lib/feature/waiting_room/controller/waiting_room_controller.dart index bdb9698..d023666 100644 --- a/lib/feature/waiting_room/controller/waiting_room_controller.dart +++ b/lib/feature/waiting_room/controller/waiting_room_controller.dart @@ -31,9 +31,6 @@ class WaitingRoomController extends GetxController { SessionResponseModel? roomData = data.data; isAdmin.value = data.isAdmin; - _socketService.initSocketConnection(); - _socketService.joinRoom(sessionCode: roomData.sessionCode, userId: _userController.userData!.id); - _socketService.roomMessages.listen((data) { final user = data["data"]; joinedUsers.assign(UserModel(id: user['user_id'], name: user['username']));