feat: adding leave page in the waiting room
This commit is contained in:
parent
da6597f42b
commit
5f54ca6c8c
|
@ -11,7 +11,7 @@ class MyApp extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return GetMaterialApp(
|
||||
title: 'Quiz App',
|
||||
locale: Get.locale ?? context.locale, // 🔁 This ensures GetX reacts to locale changes
|
||||
locale: Get.locale ?? context.locale,
|
||||
fallbackLocale: const Locale('en', 'US'),
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
|
|
|
@ -6,11 +6,13 @@ class GlobalButton extends StatelessWidget {
|
|||
final VoidCallback? onPressed;
|
||||
final String text;
|
||||
final ButtonType type;
|
||||
final Color baseColor;
|
||||
|
||||
const GlobalButton({
|
||||
super.key,
|
||||
required this.text,
|
||||
required this.onPressed,
|
||||
this.baseColor = const Color(0xFF0052CC),
|
||||
this.type = ButtonType.primary,
|
||||
});
|
||||
|
||||
|
@ -24,12 +26,12 @@ class GlobalButton extends StatelessWidget {
|
|||
|
||||
switch (type) {
|
||||
case ButtonType.primary:
|
||||
backgroundColor = const Color(0xFF0052CC);
|
||||
backgroundColor = baseColor;
|
||||
foregroundColor = Colors.white;
|
||||
break;
|
||||
case ButtonType.secondary:
|
||||
backgroundColor = Colors.white;
|
||||
foregroundColor = const Color(0xFF0052CC);
|
||||
foregroundColor = baseColor;
|
||||
borderColor = const Color(0xFF0052CC);
|
||||
break;
|
||||
case ButtonType.disabled:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class GlobalTextField extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
|
@ -10,6 +9,7 @@ class GlobalTextField extends StatelessWidget {
|
|||
final bool obscureText;
|
||||
final VoidCallback? onToggleVisibility;
|
||||
final TextInputType textInputType;
|
||||
final bool forceUpperCase;
|
||||
|
||||
const GlobalTextField(
|
||||
{super.key,
|
||||
|
@ -20,6 +20,7 @@ class GlobalTextField extends StatelessWidget {
|
|||
this.isPassword = false,
|
||||
this.obscureText = false,
|
||||
this.onToggleVisibility,
|
||||
this.forceUpperCase = false,
|
||||
this.textInputType = TextInputType.text});
|
||||
|
||||
@override
|
||||
|
@ -28,7 +29,8 @@ class GlobalTextField extends StatelessWidget {
|
|||
controller: controller,
|
||||
keyboardType: textInputType,
|
||||
obscureText: isPassword ? obscureText : false,
|
||||
maxLines: limitTextLine, // <-- ini tambahan dari limitTextLine
|
||||
maxLines: limitTextLine,
|
||||
textCapitalization: forceUpperCase ? TextCapitalization.characters : TextCapitalization.none,
|
||||
decoration: InputDecoration(
|
||||
labelText: labelText,
|
||||
labelStyle: const TextStyle(
|
||||
|
|
|
@ -58,15 +58,21 @@ class SocketService {
|
|||
}
|
||||
|
||||
void joinRoom({required String sessionCode, required String userId}) {
|
||||
socket.emit('join_room', {
|
||||
var data = {
|
||||
'session_code': sessionCode,
|
||||
'user_id': userId,
|
||||
});
|
||||
};
|
||||
print(data);
|
||||
socket.emit(
|
||||
'join_room',
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
void leaveRoom({required String sessionId, String username = "anonymous"}) {
|
||||
void leaveRoom({required String sessionId, required String userId, String username = "anonymous"}) {
|
||||
socket.emit('leave_room', {
|
||||
'session_id': sessionId,
|
||||
'user_id': userId,
|
||||
'username': username,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class JoinRoomController extends GetxController {
|
|||
return;
|
||||
}
|
||||
_socketService.initSocketConnection();
|
||||
|
||||
_socketService.joinRoom(sessionCode: code, userId: _userController.userData!.id);
|
||||
Get.toNamed(AppRoutes.waitRoomPage, arguments: WaitingRoomDTO(false, SessionResponseModel(sessionId: "", sessionCode: code)));
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ class JoinRoomView extends GetView<JoinRoomController> {
|
|||
controller: controller.codeController,
|
||||
hintText: context.tr("room_code_hint"),
|
||||
textInputType: TextInputType.text,
|
||||
forceUpperCase: true,
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
GlobalButton(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
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/waiting_room/controller/waiting_room_controller.dart';
|
||||
|
||||
|
@ -6,6 +7,9 @@ class WaitingRoomBinding extends Bindings {
|
|||
@override
|
||||
void dependencies() {
|
||||
if (!Get.isRegistered<SocketService>()) Get.put(SocketService());
|
||||
Get.lazyPut<WaitingRoomController>(() => WaitingRoomController(Get.find<SocketService>()));
|
||||
Get.lazyPut<WaitingRoomController>(() => WaitingRoomController(
|
||||
Get.find<SocketService>(),
|
||||
Get.find<UserController>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/routes/app_pages.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_listing_model.dart';
|
||||
import 'package:quiz_app/data/models/session/session_response_model.dart';
|
||||
|
@ -10,7 +12,8 @@ import 'package:quiz_app/data/services/socket_service.dart';
|
|||
|
||||
class WaitingRoomController extends GetxController {
|
||||
final SocketService _socketService;
|
||||
WaitingRoomController(this._socketService);
|
||||
final UserController _userController;
|
||||
WaitingRoomController(this._socketService, this._userController);
|
||||
|
||||
final sessionCode = ''.obs;
|
||||
final quizMeta = Rx<QuizListingModel?>(null);
|
||||
|
@ -20,6 +23,7 @@ class WaitingRoomController extends GetxController {
|
|||
final quizQuestions = <Map<String, dynamic>>[].obs;
|
||||
final isQuizStarted = false.obs;
|
||||
|
||||
SessionResponseModel? roomData;
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
@ -30,10 +34,10 @@ class WaitingRoomController extends GetxController {
|
|||
void _loadInitialData() {
|
||||
final data = Get.arguments as WaitingRoomDTO;
|
||||
|
||||
SessionResponseModel? roomData = data.data;
|
||||
roomData = data.data;
|
||||
isAdmin.value = data.isAdmin;
|
||||
|
||||
sessionCode.value = roomData.sessionCode;
|
||||
sessionCode.value = roomData!.sessionCode;
|
||||
|
||||
quizMeta.value = QuizListingModel(
|
||||
quizId: "q123",
|
||||
|
@ -49,9 +53,18 @@ class WaitingRoomController extends GetxController {
|
|||
|
||||
void _registerSocketListeners() {
|
||||
_socketService.roomMessages.listen((data) {
|
||||
final user = data["data"];
|
||||
if (user != null) {
|
||||
joinedUsers.assign(UserModel(id: user['user_id'], name: user['username']));
|
||||
if (data["type"] == "join") {
|
||||
final user = data["data"];
|
||||
if (user != null) {
|
||||
joinedUsers.assign(UserModel(id: user['user_id'], name: user['username']));
|
||||
CustomNotification.success(title: "Participan Joined", message: "${user['username']} has joined to room");
|
||||
}
|
||||
}
|
||||
|
||||
if (data["type"] == "leave") {
|
||||
final userId = data["data"];
|
||||
CustomNotification.warning(title: "Participan Leave", message: "participan leave the room");
|
||||
joinedUsers.removeWhere((e) => e.id == userId);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -86,4 +99,12 @@ class WaitingRoomController extends GetxController {
|
|||
void startQuiz() {
|
||||
_socketService.startQuiz(sessionCode: sessionCode.value);
|
||||
}
|
||||
|
||||
void leaveRoom() async {
|
||||
_socketService.leaveRoom(sessionId: roomData!.sessionId, userId: _userController.userData!.id);
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
|
||||
await Future.delayed(Duration(seconds: 2));
|
||||
_socketService.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,13 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
|||
GlobalButton(
|
||||
text: "Mulai Kuis",
|
||||
onPressed: controller.startQuiz,
|
||||
),
|
||||
)
|
||||
else
|
||||
GlobalButton(
|
||||
text: "Tinggalkan Ruangan",
|
||||
onPressed: controller.leaveRoom,
|
||||
baseColor: const Color.fromARGB(255, 204, 14, 0),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
|
@ -68,6 +74,7 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
|||
if (quiz == null) return const SizedBox.shrink();
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.background,
|
||||
border: Border.all(color: AppColors.borderLight),
|
||||
|
|
Loading…
Reference in New Issue