fix: waiting room localization and adding room name
This commit is contained in:
parent
a7f5f98cf5
commit
0283806cf3
|
@ -138,6 +138,18 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"get_ready": "Get Ready",
|
"get_ready": "Get Ready",
|
||||||
"quiz_starting_soon" : "Quiz Starting Soon"
|
"quiz_starting_soon": "Quiz Starting Soon",
|
||||||
|
|
||||||
|
"waiting_room": {
|
||||||
|
"title": "Waiting Room",
|
||||||
|
"participants_joined": "Participants Joined:",
|
||||||
|
"leave_room": "Leave Room",
|
||||||
|
"session_code": "Session Code:",
|
||||||
|
"copy_code": "Copy Code",
|
||||||
|
"quiz_info": "Quiz Information:",
|
||||||
|
"quiz_title": "Title",
|
||||||
|
"quiz_description": "Description",
|
||||||
|
"quiz_total_question": "Total Questions",
|
||||||
|
"quiz_duration": "Duration"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,5 +122,17 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"get_ready": "Bersiaplah",
|
"get_ready": "Bersiaplah",
|
||||||
"quiz_starting_soon": "Kuis akan segera dimulai"
|
"quiz_starting_soon": "Kuis akan segera dimulai",
|
||||||
|
"waiting_room": {
|
||||||
|
"title": "Ruang Tunggu",
|
||||||
|
"participants_joined": "Peserta Bergabung:",
|
||||||
|
"leave_room": "Keluar dari Ruangan",
|
||||||
|
"session_code": "Kode Sesi:",
|
||||||
|
"copy_code": "Salin Kode",
|
||||||
|
"quiz_info": "Informasi Kuis:",
|
||||||
|
"quiz_title": "Judul",
|
||||||
|
"quiz_description": "Deskripsi",
|
||||||
|
"quiz_total_question": "Total Pertanyaan",
|
||||||
|
"quiz_duration": "Durasi"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,5 +124,17 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"get_ready": "Bersedia",
|
"get_ready": "Bersedia",
|
||||||
"quiz_starting_soon": "Kuiz akan bermula sebentar lagi"
|
"quiz_starting_soon": "Kuiz akan bermula sebentar lagi",
|
||||||
|
"waiting_room": {
|
||||||
|
"title": "Bilik Menunggu",
|
||||||
|
"participants_joined": "Peserta Telah Sertai:",
|
||||||
|
"leave_room": "Tinggalkan Bilik",
|
||||||
|
"session_code": "Kod Sesi:",
|
||||||
|
"copy_code": "Salin Kod",
|
||||||
|
"quiz_info": "Maklumat Kuiz:",
|
||||||
|
"quiz_title": "Tajuk",
|
||||||
|
"quiz_description": "Penerangan",
|
||||||
|
"quiz_total_question": "Jumlah Soalan",
|
||||||
|
"quiz_duration": "Tempoh"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
extension StringCasingExtension on String {
|
||||||
|
String toTitleCase() {
|
||||||
|
return split(' ').map((word) => word.isNotEmpty ? '${word[0].toUpperCase()}${word.substring(1).toLowerCase()}' : '').join(' ');
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'package:quiz_app/data/models/user/user_model.dart';
|
||||||
class SessionInfo {
|
class SessionInfo {
|
||||||
final String id;
|
final String id;
|
||||||
final String sessionCode;
|
final String sessionCode;
|
||||||
|
final String roomName;
|
||||||
final String quizId;
|
final String quizId;
|
||||||
final String hostId;
|
final String hostId;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
|
@ -16,6 +17,7 @@ class SessionInfo {
|
||||||
SessionInfo({
|
SessionInfo({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.sessionCode,
|
required this.sessionCode,
|
||||||
|
required this.roomName,
|
||||||
required this.quizId,
|
required this.quizId,
|
||||||
required this.hostId,
|
required this.hostId,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
|
@ -31,6 +33,7 @@ class SessionInfo {
|
||||||
return SessionInfo(
|
return SessionInfo(
|
||||||
id: json['id'],
|
id: json['id'],
|
||||||
sessionCode: json['session_code'],
|
sessionCode: json['session_code'],
|
||||||
|
roomName: json["room_name"],
|
||||||
quizId: json['quiz_id'],
|
quizId: json['quiz_id'],
|
||||||
hostId: json['host_id'],
|
hostId: json['host_id'],
|
||||||
createdAt: DateTime.parse(json['created_at']),
|
createdAt: DateTime.parse(json['created_at']),
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
class SessionRequestModel {
|
class SessionRequestModel {
|
||||||
final String quizId;
|
final String quizId;
|
||||||
final String hostId;
|
final String hostId;
|
||||||
|
final String roomName;
|
||||||
final int limitParticipan;
|
final int limitParticipan;
|
||||||
|
|
||||||
SessionRequestModel({
|
SessionRequestModel({
|
||||||
required this.quizId,
|
required this.quizId,
|
||||||
required this.hostId,
|
required this.hostId,
|
||||||
|
required this.roomName,
|
||||||
required this.limitParticipan,
|
required this.limitParticipan,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13,6 +15,7 @@ class SessionRequestModel {
|
||||||
return SessionRequestModel(
|
return SessionRequestModel(
|
||||||
quizId: json['quiz_id'],
|
quizId: json['quiz_id'],
|
||||||
hostId: json['host_id'],
|
hostId: json['host_id'],
|
||||||
|
roomName: json['room_name'],
|
||||||
limitParticipan: json['limit_participan'],
|
limitParticipan: json['limit_participan'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +24,7 @@ class SessionRequestModel {
|
||||||
return {
|
return {
|
||||||
'quiz_id': quizId,
|
'quiz_id': quizId,
|
||||||
'host_id': hostId,
|
'host_id': hostId,
|
||||||
|
'room_name': roomName,
|
||||||
'limit_participan': limitParticipan,
|
'limit_participan': limitParticipan,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,7 @@ class SessionService extends GetxService {
|
||||||
|
|
||||||
Future<BaseResponseModel<SessionResponseModel>?> createSession(SessionRequestModel data) async {
|
Future<BaseResponseModel<SessionResponseModel>?> createSession(SessionRequestModel data) async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.post(APIEndpoint.session, data: {
|
final response = await _dio.post(APIEndpoint.session, data: data.toJson());
|
||||||
'quiz_id': data.quizId,
|
|
||||||
'host_id': data.hostId,
|
|
||||||
'limit_participan': data.limitParticipan,
|
|
||||||
});
|
|
||||||
if (response.statusCode != 201) {
|
if (response.statusCode != 201) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,32 +33,32 @@ class JoinRoomView extends GetView<JoinRoomController> {
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
TweenAnimationBuilder<double>(
|
// TweenAnimationBuilder<double>(
|
||||||
duration: const Duration(seconds: 1),
|
// duration: const Duration(seconds: 1),
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
// tween: Tween(begin: 0.0, end: 1.0),
|
||||||
builder: (context, value, child) {
|
// builder: (context, value, child) {
|
||||||
return Transform.scale(
|
// return Transform.scale(
|
||||||
scale: value,
|
// scale: value,
|
||||||
child: child,
|
// child: child,
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
child: Container(
|
// child: Container(
|
||||||
padding: EdgeInsets.all(22),
|
// padding: EdgeInsets.all(22),
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
color: AppColors.primaryBlue.withValues(alpha: 0.05),
|
// color: AppColors.primaryBlue.withValues(alpha: 0.05),
|
||||||
shape: BoxShape.circle,
|
// shape: BoxShape.circle,
|
||||||
border: Border.all(
|
// border: Border.all(
|
||||||
color: AppColors.primaryBlue.withValues(alpha: 0.15),
|
// color: AppColors.primaryBlue.withValues(alpha: 0.15),
|
||||||
width: 2,
|
// width: 2,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
child: Icon(
|
// child: Icon(
|
||||||
LucideIcons.trophy,
|
// LucideIcons.trophy,
|
||||||
size: 70,
|
// size: 70,
|
||||||
color: AppColors.primaryBlue,
|
// color: AppColors.primaryBlue,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
|
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ class RoomMakerController extends GetxController {
|
||||||
SessionRequestModel(
|
SessionRequestModel(
|
||||||
quizId: quiz.quizId,
|
quizId: quiz.quizId,
|
||||||
hostId: _userController.userData!.id,
|
hostId: _userController.userData!.id,
|
||||||
|
roomName: nameTC.text,
|
||||||
limitParticipan: int.parse(maxPlayerTC.text),
|
limitParticipan: int.parse(maxPlayerTC.text),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,6 +16,7 @@ class WaitingRoomController extends GetxController {
|
||||||
WaitingRoomController(this._socketService, this._userController);
|
WaitingRoomController(this._socketService, this._userController);
|
||||||
|
|
||||||
final sessionCode = ''.obs;
|
final sessionCode = ''.obs;
|
||||||
|
final roomName = "".obs;
|
||||||
String sessionId = '';
|
String sessionId = '';
|
||||||
final quizMeta = Rx<QuizInfo?>(null);
|
final quizMeta = Rx<QuizInfo?>(null);
|
||||||
final joinedUsers = <UserModel>[].obs;
|
final joinedUsers = <UserModel>[].obs;
|
||||||
|
@ -42,6 +43,7 @@ class WaitingRoomController extends GetxController {
|
||||||
sessionId = roomData!.sessionId;
|
sessionId = roomData!.sessionId;
|
||||||
|
|
||||||
quizMeta.value = data.quizInfo;
|
quizMeta.value = data.quizInfo;
|
||||||
|
roomName.value = data.sessionInfo.roomName;
|
||||||
|
|
||||||
joinedUsers.assignAll(data.sessionInfo.participants);
|
joinedUsers.assignAll(data.sessionInfo.participants);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:quiz_app/app/const/text/string_extension.dart';
|
||||||
|
import 'package:quiz_app/app/const/text/text_style.dart';
|
||||||
import 'package:quiz_app/component/global_button.dart';
|
import 'package:quiz_app/component/global_button.dart';
|
||||||
import 'package:quiz_app/data/models/quiz/quiz_info_model.dart';
|
import 'package:quiz_app/data/models/quiz/quiz_info_model.dart';
|
||||||
import 'package:quiz_app/data/models/user/user_model.dart';
|
import 'package:quiz_app/data/models/user/user_model.dart';
|
||||||
|
@ -11,7 +14,9 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.background,
|
backgroundColor: AppColors.background,
|
||||||
appBar: AppBar(title: const Text("Waiting Room")),
|
appBar: AppBar(
|
||||||
|
title: Text(tr("waiting_room.title"), style: AppTextStyles.title),
|
||||||
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
|
@ -22,25 +27,39 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: Obx(() => Text(
|
||||||
|
controller.roomName.value.toTitleCase(),
|
||||||
|
style: AppTextStyles.title,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
_buildQuizMeta(quiz!),
|
_buildQuizMeta(quiz!),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildSessionCode(context, session),
|
_buildSessionCode(context, session),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const Text("Peserta yang Bergabung:", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
Text(
|
||||||
|
tr("waiting_room.participants_joined"),
|
||||||
|
style: AppTextStyles.subtitle.copyWith(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColors.darkText,
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Expanded(child: Obx(() => _buildUserList(users.toList()))),
|
Expanded(child: Obx(() => _buildUserList(users.toList()))),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
if (controller.isAdmin.value)
|
controller.isAdmin.value
|
||||||
GlobalButton(
|
? GlobalButton(
|
||||||
text: "Mulai Kuis",
|
text: tr("start_quiz"),
|
||||||
onPressed: controller.startQuiz,
|
onPressed: controller.startQuiz,
|
||||||
)
|
)
|
||||||
else
|
: GlobalButton(
|
||||||
GlobalButton(
|
text: tr("waiting_room.leave_room"),
|
||||||
text: "Tinggalkan Ruangan",
|
onPressed: controller.leaveRoom,
|
||||||
onPressed: controller.leaveRoom,
|
baseColor: const Color.fromARGB(255, 204, 14, 0),
|
||||||
baseColor: const Color.fromARGB(255, 204, 14, 0),
|
)
|
||||||
)
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
@ -52,18 +71,19 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.primaryBlue.withValues(alpha: 0.05),
|
color: AppColors.accentBlue.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
border: Border.all(color: AppColors.primaryBlue),
|
border: Border.all(color: AppColors.primaryBlue),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const Text("Session Code: ", style: TextStyle(fontWeight: FontWeight.bold)),
|
Text(tr("waiting_room.session_code"), style: AppTextStyles.statValue),
|
||||||
SelectableText(code, style: const TextStyle(fontSize: 16)),
|
const SizedBox(width: 4),
|
||||||
|
SelectableText(code, style: AppTextStyles.body.copyWith(fontSize: 16)),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.copy),
|
icon: const Icon(Icons.copy),
|
||||||
tooltip: 'Salin Kode',
|
tooltip: tr("waiting_room.copy_code"),
|
||||||
onPressed: () => controller.copySessionCode(context),
|
onPressed: () => controller.copySessionCode(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -72,7 +92,6 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildQuizMeta(QuizInfo quiz) {
|
Widget _buildQuizMeta(QuizInfo quiz) {
|
||||||
// if (quiz == null) return const SizedBox.shrink();
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
|
@ -84,12 +103,12 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text("Informasi Kuis:", style: TextStyle(fontWeight: FontWeight.bold)),
|
Text(tr("waiting_room.quiz_info"), style: AppTextStyles.subtitle.copyWith(fontWeight: FontWeight.bold)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text("Judul: ${quiz.title}"),
|
Text("${tr("waiting_room.quiz_title")}: ${quiz.title}", style: AppTextStyles.body),
|
||||||
Text("Deskripsi: ${quiz.description}"),
|
Text("${tr("waiting_room.quiz_description")}: ${quiz.description}", style: AppTextStyles.body),
|
||||||
Text("Jumlah Soal: ${quiz.totalQuiz}"),
|
Text("${tr("waiting_room.quiz_total_question")}: ${quiz.totalQuiz}", style: AppTextStyles.body),
|
||||||
Text("Durasi: ${quiz.limitDuration ~/ 60} menit"),
|
Text("${tr("waiting_room.quiz_duration")}: ${quiz.limitDuration ~/ 60} min", style: AppTextStyles.body),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -110,9 +129,9 @@ class WaitingRoomView extends GetView<WaitingRoomController> {
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
CircleAvatar(child: Text(user.username[0])),
|
CircleAvatar(child: Text(user.username[0].toUpperCase())),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(user.username, style: const TextStyle(fontSize: 16)),
|
Text(user.username, style: AppTextStyles.body.copyWith(fontSize: 16)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue