update
This commit is contained in:
parent
8a328e7dd4
commit
9f049952e8
|
@ -15,6 +15,7 @@ import androidx.navigation.navArgument
|
||||||
import com.example.lexilearn.data.model.MaterialDataModel
|
import com.example.lexilearn.data.model.MaterialDataModel
|
||||||
import com.example.lexilearn.data.model.UserDataModel
|
import com.example.lexilearn.data.model.UserDataModel
|
||||||
import com.example.lexilearn.data.repository.UserRepository
|
import com.example.lexilearn.data.repository.UserRepository
|
||||||
|
import com.example.lexilearn.ui.theme.LexiLearnTheme
|
||||||
import com.example.lexilearn.ui.views.pDetailMaterial.DetailMaterialScreen
|
import com.example.lexilearn.ui.views.pDetailMaterial.DetailMaterialScreen
|
||||||
import com.example.lexilearn.ui.views.pHome.HomeScreen
|
import com.example.lexilearn.ui.views.pHome.HomeScreen
|
||||||
import com.example.lexilearn.ui.views.pLearAlphabet.LearnAlphabetScreen
|
import com.example.lexilearn.ui.views.pLearAlphabet.LearnAlphabetScreen
|
||||||
|
@ -75,7 +76,9 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setContent {
|
setContent {
|
||||||
MyApp()
|
LexiLearnTheme {
|
||||||
|
MyApp() // Menggunakan MyApp dengan tema LexiLearn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,29 +18,30 @@ class FirebaseHelper(private val context: Context) {
|
||||||
|
|
||||||
// 🔥 Fungsi untuk mengambil data berdasarkan filterMaterial (kode lama, tetap dipertahankan)
|
// 🔥 Fungsi untuk mengambil data berdasarkan filterMaterial (kode lama, tetap dipertahankan)
|
||||||
fun fetchMaterials(filterMaterial: String, callback: (List<MaterialDataModel>) -> Unit) {
|
fun fetchMaterials(filterMaterial: String, callback: (List<MaterialDataModel>) -> Unit) {
|
||||||
val databaseReference: DatabaseReference =
|
val databaseReference: DatabaseReference =
|
||||||
FirebaseDatabase.getInstance().getReference("data/$filterMaterial")
|
FirebaseDatabase.getInstance().getReference("data/$filterMaterial")
|
||||||
|
|
||||||
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
||||||
override fun onDataChange(snapshot: DataSnapshot) {
|
override fun onDataChange(snapshot: DataSnapshot) {
|
||||||
val materialList = mutableListOf<MaterialDataModel>()
|
val materialList = mutableListOf<MaterialDataModel>()
|
||||||
for (materialSnapshot in snapshot.children) {
|
for (materialSnapshot in snapshot.children) {
|
||||||
val material = materialSnapshot.getValue(MaterialDataModel::class.java)
|
val material = materialSnapshot.getValue(MaterialDataModel::class.java)
|
||||||
material?.let { materialList.add(it) }
|
material?.let { materialList.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedPrefHelper.saveMaterialList(filterMaterial, materialList)
|
sharedPrefHelper.saveMaterialList(filterMaterial, materialList)
|
||||||
callback(materialList)
|
callback(materialList)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCancelled(error: DatabaseError) {
|
override fun onCancelled(error: DatabaseError) {
|
||||||
Log.e("FirebaseHelper", "Error: ${error.message}")
|
Log.e("FirebaseHelper", "Error: ${error.message}")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchAllMaterials(callback: (List<MaterialDataModel>) -> Unit) {
|
fun fetchAllMaterials(callback: (List<MaterialDataModel>) -> Unit) {
|
||||||
val databaseReference: DatabaseReference = FirebaseDatabase.getInstance().getReference("data")
|
val databaseReference: DatabaseReference =
|
||||||
|
FirebaseDatabase.getInstance().getReference("data")
|
||||||
|
|
||||||
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
||||||
override fun onDataChange(snapshot: DataSnapshot) {
|
override fun onDataChange(snapshot: DataSnapshot) {
|
||||||
|
@ -102,8 +103,10 @@ class FirebaseHelper(private val context: Context) {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
fun loginUser(callback: (Boolean, String?) -> Unit) {
|
fun loginUser(callback: (Boolean, String?) -> Unit) {
|
||||||
val databaseReference: DatabaseReference = FirebaseDatabase.getInstance().getReference("users")
|
val databaseReference: DatabaseReference =
|
||||||
val userId = sharedPrefHelper.getUserId() // Ambil ID pengguna yang disimpan di SharedPreferences
|
FirebaseDatabase.getInstance().getReference("users")
|
||||||
|
val userId =
|
||||||
|
sharedPrefHelper.getUserId() // Ambil ID pengguna yang disimpan di SharedPreferences
|
||||||
|
|
||||||
if (userId.isNullOrEmpty()) {
|
if (userId.isNullOrEmpty()) {
|
||||||
callback(false, null) // Jika tidak ada ID tersimpan
|
callback(false, null) // Jika tidak ada ID tersimpan
|
||||||
|
@ -145,20 +148,19 @@ class FirebaseHelper(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateUser(updatedUser: UserDataModel, callback: (Boolean) -> Unit) {
|
fun updateUser(updatedUser: UserDataModel, callback: (Boolean) -> Unit) {
|
||||||
val getUserData = sharedPrefHelper.getUserData()
|
val userId = sharedPrefHelper.getUserId()
|
||||||
val userId = sharedPrefHelper.getUserId() // Ambil ID pengguna yang disimpan di SharedPreferences
|
val databaseReference = FirebaseDatabase.getInstance().getReference("users")
|
||||||
val databaseReference = FirebaseDatabase.getInstance().getReference("users")
|
val newData = mapOf(
|
||||||
val newData = mapOf(
|
"name" to updatedUser.name,
|
||||||
"name" to updatedUser.name,
|
"age" to updatedUser.age,
|
||||||
"age" to updatedUser.age,
|
)
|
||||||
)
|
if (userId != null) {
|
||||||
if(userId!=null){
|
databaseReference.child(userId).updateChildren(newData).addOnCompleteListener { task ->
|
||||||
databaseReference.child(userId).updateChildren(newData).addOnCompleteListener { task ->
|
callback(task.isSuccessful)
|
||||||
callback(task.isSuccessful)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 🔥 Fungsi Fetch User Data Berdasarkan ID (Dapatkan data user setelah login)
|
// ✅ 🔥 Fungsi Fetch User Data Berdasarkan ID (Dapatkan data user setelah login)
|
||||||
fun fetchUserData(callback: (UserDataModel?) -> Unit) {
|
fun fetchUserData(callback: (UserDataModel?) -> Unit) {
|
||||||
|
@ -169,7 +171,8 @@ class FirebaseHelper(private val context: Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val databaseReference: DatabaseReference = FirebaseDatabase.getInstance().getReference("users/$userId")
|
val databaseReference: DatabaseReference =
|
||||||
|
FirebaseDatabase.getInstance().getReference("users/$userId")
|
||||||
|
|
||||||
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
|
||||||
override fun onDataChange(snapshot: DataSnapshot) {
|
override fun onDataChange(snapshot: DataSnapshot) {
|
||||||
|
@ -183,6 +186,7 @@ class FirebaseHelper(private val context: Context) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchTop10Scores(callback: (List<Pair<String, Int>>) -> Unit) {
|
fun fetchTop10Scores(callback: (List<Pair<String, Int>>) -> Unit) {
|
||||||
val todayDate = getTodayDate()
|
val todayDate = getTodayDate()
|
||||||
val databaseReference: DatabaseReference =
|
val databaseReference: DatabaseReference =
|
||||||
|
|
|
@ -10,52 +10,38 @@ import kotlin.random.Random
|
||||||
|
|
||||||
class QuizRepository {
|
class QuizRepository {
|
||||||
|
|
||||||
/**
|
fun generateQuestion(
|
||||||
* Fungsi ini akan membuat soal dengan mode soal & jawaban yang DITENTUKAN oleh parameter.
|
material: MaterialDataModel,
|
||||||
*/
|
questionMode: Int,
|
||||||
fun generateQuestion(
|
answerMode: Int
|
||||||
material: MaterialDataModel,
|
): QuizQuestion {
|
||||||
questionMode: Int,
|
val questionType = when (questionMode) {
|
||||||
answerMode: Int
|
1 -> listOf(QuestionType.TEXT, QuestionType.IMAGE).random()
|
||||||
): QuizQuestion {
|
2 -> QuestionType.AUDIO
|
||||||
val questionType = when (questionMode) {
|
else -> QuestionType.TEXT
|
||||||
1 -> listOf(QuestionType.TEXT, QuestionType.IMAGE).random() // Text atau Image
|
}
|
||||||
2 -> QuestionType.AUDIO // Hanya Audio
|
|
||||||
else -> QuestionType.TEXT // Default ke Text
|
|
||||||
}
|
|
||||||
|
|
||||||
val question = when (questionType) {
|
val question = when (questionType) {
|
||||||
QuestionType.TEXT -> listOf(material.idName, material.idDescription).random()
|
QuestionType.TEXT -> listOf(material.idName, material.idDescription).random()
|
||||||
QuestionType.IMAGE -> material.image
|
QuestionType.IMAGE -> material.image
|
||||||
QuestionType.AUDIO -> material.enName
|
QuestionType.AUDIO -> material.enName
|
||||||
} ?: "Soal tidak tersedia"
|
} ?: "Soal tidak tersedia"
|
||||||
|
|
||||||
val answerType = when (answerMode) {
|
val answerType = when (answerMode) {
|
||||||
1 -> AnswerType.FULL_WORD
|
1 -> AnswerType.FULL_WORD
|
||||||
2 -> AnswerType.SHUFFLED_LETTERS
|
2 -> AnswerType.SHUFFLED_LETTERS
|
||||||
else -> AnswerType.FULL_WORD
|
else -> AnswerType.FULL_WORD
|
||||||
}
|
}
|
||||||
|
|
||||||
return QuizQuestion(
|
return QuizQuestion(
|
||||||
questionType = questionType,
|
questionType = questionType,
|
||||||
question = question,
|
question = question,
|
||||||
correctAnswer = QuizAnswer(
|
correctAnswer = QuizAnswer(
|
||||||
answerType = answerType,
|
answerType = answerType,
|
||||||
correctWord = material.enName
|
correctWord = material.enName
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Fungsi ini akan membuat soal dengan mode soal & jawaban yang DIPILIH SECARA ACAK.
|
|
||||||
*/
|
|
||||||
fun generateRandomQuestion(material: MaterialDataModel): QuizQuestion {
|
|
||||||
val randomQuestionMode = Random.nextInt(1, 3) // Acak antara 1 (Text/Image) atau 2 (Audio)
|
|
||||||
val randomAnswerMode =
|
|
||||||
Random.nextInt(1, 3) // Acak antara 1 (FULL_WORD) atau 2 (SHUFFLED_LETTERS)
|
|
||||||
|
|
||||||
return generateQuestion(material, randomQuestionMode, randomAnswerMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getRandomMaterials(
|
fun getRandomMaterials(
|
||||||
nData: Int,
|
nData: Int,
|
||||||
|
|
|
@ -40,7 +40,8 @@ class UserRepository(private val context: Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
val userRef =
|
||||||
|
FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||||
|
|
||||||
userRef.get().addOnSuccessListener { snapshot ->
|
userRef.get().addOnSuccessListener { snapshot ->
|
||||||
val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
||||||
|
@ -85,7 +86,8 @@ class UserRepository(private val context: Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
val userRef =
|
||||||
|
FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||||
userRef.get().addOnSuccessListener { snapshot ->
|
userRef.get().addOnSuccessListener { snapshot ->
|
||||||
callback(snapshot.getValue(Int::class.java) ?: 0)
|
callback(snapshot.getValue(Int::class.java) ?: 0)
|
||||||
}.addOnFailureListener {
|
}.addOnFailureListener {
|
||||||
|
|
|
@ -7,31 +7,31 @@ import androidx.compose.ui.text.font.FontFamily
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.example.lexilearn.R
|
import com.example.lexilearn.R
|
||||||
|
val _fredokaOne = FontFamily(
|
||||||
|
Font(R.font.fredoka) // Pastikan nama file sesuai
|
||||||
|
)
|
||||||
|
|
||||||
// Set of Material typography styles to start with
|
// Set of Material typography styles to start with
|
||||||
val Typography = Typography(
|
val Typography = Typography(
|
||||||
bodyLarge = TextStyle(
|
|
||||||
fontFamily = FontFamily(Font(R.font.inter)),
|
displayLarge = TextStyle(fontFamily = _fredokaOne, fontSize = 57.sp), // Gaya displayLarge
|
||||||
fontWeight = FontWeight.Normal,
|
displayMedium = TextStyle(fontFamily = _fredokaOne, fontSize = 45.sp), // Gaya displayMedium
|
||||||
fontSize = 16.sp,
|
displaySmall = TextStyle(fontFamily = _fredokaOne, fontSize = 36.sp), // Gaya displaySmall
|
||||||
lineHeight = 24.sp,
|
|
||||||
letterSpacing = 0.5.sp
|
headlineLarge = TextStyle(fontFamily = _fredokaOne, fontSize = 32.sp), // Gaya headlineLarge
|
||||||
)
|
headlineMedium = TextStyle(fontFamily = _fredokaOne, fontSize = 28.sp), // Gaya headlineMedium
|
||||||
/* Other default text styles to override
|
headlineSmall = TextStyle(fontFamily = _fredokaOne, fontSize = 24.sp), // Gaya headlineSmall
|
||||||
titleLarge = TextStyle(
|
|
||||||
fontFamily = FontFamily.Default,
|
titleLarge = TextStyle(fontFamily = _fredokaOne, fontSize = 22.sp), // Gaya titleLarge
|
||||||
fontWeight = FontWeight.Normal,
|
titleMedium = TextStyle(fontFamily = _fredokaOne, fontSize = 20.sp), // Gaya titleMedium
|
||||||
fontSize = 22.sp,
|
titleSmall = TextStyle(fontFamily = _fredokaOne, fontSize = 18.sp), // Gaya titleSmall
|
||||||
lineHeight = 28.sp,
|
|
||||||
letterSpacing = 0.sp
|
bodyLarge = TextStyle(fontFamily = _fredokaOne, fontSize = 16.sp), // Gaya bodyLarge
|
||||||
),
|
bodyMedium = TextStyle(fontFamily = _fredokaOne, fontSize = 14.sp), // Gaya bodyMedium
|
||||||
labelSmall = TextStyle(
|
bodySmall = TextStyle(fontFamily = _fredokaOne, fontSize = 12.sp), // Gaya bodySmall
|
||||||
fontFamily = FontFamily.Default,
|
|
||||||
fontWeight = FontWeight.Medium,
|
labelLarge = TextStyle(fontFamily = _fredokaOne, fontSize = 14.sp), // Gaya labelLarge
|
||||||
fontSize = 11.sp,
|
labelMedium = TextStyle(fontFamily = _fredokaOne, fontSize = 12.sp), // Gaya labelMedium
|
||||||
lineHeight = 16.sp,
|
labelSmall = TextStyle(fontFamily = _fredokaOne, fontSize = 10.sp) // Gaya labelSm
|
||||||
letterSpacing = 0.5.sp
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,11 @@ import com.example.lexilearn.ui.theme.ctextBlack
|
||||||
import com.example.lexilearn.ui.theme.ctextGray
|
import com.example.lexilearn.ui.theme.ctextGray
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DetailMaterialScreen(navController: NavController, materialListData: List<MaterialDataModel>, indexValue: Int) {
|
fun DetailMaterialScreen(
|
||||||
|
navController: NavController,
|
||||||
|
materialListData: List<MaterialDataModel>,
|
||||||
|
indexValue: Int
|
||||||
|
) {
|
||||||
val viewModel: DetailMaterialViewModel = viewModel()
|
val viewModel: DetailMaterialViewModel = viewModel()
|
||||||
LaunchedEffect(materialListData) {
|
LaunchedEffect(materialListData) {
|
||||||
viewModel.fetchMaterial(materialListData)
|
viewModel.fetchMaterial(materialListData)
|
||||||
|
@ -98,8 +102,8 @@ fun DetailMaterialScreen(navController: NavController, materialListData: List<Ma
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(120.dp) // 🔥 Ukuran gambar
|
.size(120.dp)
|
||||||
.clip(RoundedCornerShape(12.dp)) // 🔥 Memberikan sudut lengkung (radius)
|
.clip(RoundedCornerShape(12.dp))
|
||||||
) {
|
) {
|
||||||
FirebaseImage(
|
FirebaseImage(
|
||||||
path = dataMat.image,
|
path = dataMat.image,
|
||||||
|
@ -144,7 +148,7 @@ fun DetailMaterialScreen(navController: NavController, materialListData: List<Ma
|
||||||
} // 🔥 Ukuran tombol bisa disesuaikan
|
} // 🔥 Ukuran tombol bisa disesuaikan
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.VolumeUp, // 🔥 Ikon Speaker dari Material Icons
|
imageVector = Icons.Filled.VolumeUp,
|
||||||
contentDescription = "Speaker Icon",
|
contentDescription = "Speaker Icon",
|
||||||
tint = Color.Black // 🔥 Warna ikon
|
tint = Color.Black // 🔥 Warna ikon
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Locale
|
||||||
|
|
||||||
class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
private val totalDataCompetition = 3
|
private val totalDataCompetition = 5
|
||||||
|
|
||||||
val materialRepository = MaterialRepository(application)
|
val materialRepository = MaterialRepository(application)
|
||||||
val userRepository = UserRepository(application)
|
val userRepository = UserRepository(application)
|
||||||
|
@ -67,21 +67,18 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
|
|
||||||
// 🔥 Fungsi untuk mengambil 10 skor tertinggi secara real-time dari Firebase
|
// 🔥 Fungsi untuk mengambil 10 skor tertinggi secara real-time dari Firebase
|
||||||
fun fetchTop10Scores() {
|
private fun fetchTop10Scores() {
|
||||||
val todayDate = getTodayDate()
|
val todayDate = getTodayDate()
|
||||||
val dateRef = database.child(todayDate)
|
val dateRef = database.child(todayDate)
|
||||||
|
|
||||||
dateRef.orderByChild("score").limitToLast(10) // Ambil 10 skor tertinggi
|
dateRef.orderByChild("score").limitToLast(10)
|
||||||
.addValueEventListener(object : ValueEventListener {
|
.addValueEventListener(object : ValueEventListener {
|
||||||
override fun onDataChange(snapshot: DataSnapshot) {
|
override fun onDataChange(snapshot: DataSnapshot) {
|
||||||
val scoreList = mutableListOf<CompetitionScore>()
|
val scoreList = mutableListOf<CompetitionScore>()
|
||||||
|
|
||||||
for (scoreSnapshot in snapshot.children) {
|
for (scoreSnapshot in snapshot.children) {
|
||||||
val scoreData = scoreSnapshot.getValue(CompetitionScore::class.java)
|
val scoreData = scoreSnapshot.getValue(CompetitionScore::class.java)
|
||||||
scoreData?.let { scoreList.add(it) }
|
scoreData?.let { scoreList.add(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Urutkan dari yang tertinggi ke terendah
|
|
||||||
_topScores.value = scoreList.sortedByDescending { it.score }
|
_topScores.value = scoreList.sortedByDescending { it.score }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ fun LearnNumberScreen(navController: NavController) {
|
||||||
Surface(modifier = Modifier.fillMaxSize()) {
|
Surface(modifier = Modifier.fillMaxSize()) {
|
||||||
GradientQuiz(
|
GradientQuiz(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
headerText = "Belajar Alfabet Inggris",
|
headerText = "Belajar Angka Inggris",
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
|
|
|
@ -45,7 +45,6 @@ class NavMaterialViewModel(application: Application) : AndroidViewModel(applicat
|
||||||
_sizeUnlock.value = value
|
_sizeUnlock.value = value
|
||||||
}
|
}
|
||||||
repository.getMaterialData(materialId) { materials ->
|
repository.getMaterialData(materialId) { materials ->
|
||||||
// val filteredMaterials = materials.filter { it.category == materialId }
|
|
||||||
_materialList.value = materials.chunked(3)
|
_materialList.value = materials.chunked(3)
|
||||||
if (materials[0].category == "animal") {
|
if (materials[0].category == "animal") {
|
||||||
_textTitle.value = "hewan"
|
_textTitle.value = "hewan"
|
||||||
|
|
|
@ -53,12 +53,14 @@ import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
import androidx.constraintlayout.compose.ConstraintLayout
|
import androidx.constraintlayout.compose.ConstraintLayout
|
||||||
import com.example.lexilearn.data.model.QuestionType
|
import com.example.lexilearn.data.model.QuestionType
|
||||||
|
import com.example.lexilearn.domain.models.ModelQuestion
|
||||||
import com.example.lexilearn.ui.components.CardQuiz
|
import com.example.lexilearn.ui.components.CardQuiz
|
||||||
import com.example.lexilearn.ui.components.DraggableAnswerCard
|
import com.example.lexilearn.ui.components.DraggableAnswerCard
|
||||||
import com.example.lexilearn.ui.components.FirebaseImage
|
import com.example.lexilearn.ui.components.FirebaseImage
|
||||||
import com.example.lexilearn.ui.components.GradientQuiz
|
import com.example.lexilearn.ui.components.GradientQuiz
|
||||||
import com.example.lexilearn.ui.components.MyShadowCard
|
import com.example.lexilearn.ui.components.MyShadowCard
|
||||||
import com.example.lexilearn.ui.theme.cAccent
|
import com.example.lexilearn.ui.theme.cAccent
|
||||||
|
import com.example.lexilearn.ui.theme.ctextBlack
|
||||||
import com.example.lexilearn.ui.theme.ctextGray
|
import com.example.lexilearn.ui.theme.ctextGray
|
||||||
import com.example.lexilearn.ui.theme.ctextWhite
|
import com.example.lexilearn.ui.theme.ctextWhite
|
||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
|
@ -73,7 +75,6 @@ fun QuizScreen(
|
||||||
indexValue: Int,
|
indexValue: Int,
|
||||||
quizViewModel: QuizViewModel = viewModel()
|
quizViewModel: QuizViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
println("testco tipe: ${typeQuiz}, index = ${indexValue}")
|
|
||||||
val question by quizViewModel.currentQuestion.collectAsState()
|
val question by quizViewModel.currentQuestion.collectAsState()
|
||||||
val isButtonVisible by quizViewModel.isButtonVisible
|
val isButtonVisible by quizViewModel.isButtonVisible
|
||||||
val isAnswerCorrect by quizViewModel.isAnswerCorrect.collectAsState()
|
val isAnswerCorrect by quizViewModel.isAnswerCorrect.collectAsState()
|
||||||
|
@ -222,7 +223,7 @@ fun QuizScreen(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "Score: $liveCurrentScore",
|
text = "Point: $liveCurrentScore",
|
||||||
color = cAccent,
|
color = cAccent,
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
|
@ -256,6 +257,7 @@ fun QuizScreen(
|
||||||
Text(
|
Text(
|
||||||
text = question!!.question,
|
text = question!!.question,
|
||||||
fontSize = 20.sp,
|
fontSize = 20.sp,
|
||||||
|
color = ctextBlack,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
modifier = Modifier.padding(12.dp)
|
modifier = Modifier.padding(12.dp)
|
||||||
)
|
)
|
||||||
|
@ -366,10 +368,7 @@ fun QuizScreen(
|
||||||
rect
|
rect
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
quizViewModel.updateQuestionShuffled(
|
val newDt = dt.copy()
|
||||||
ind,
|
|
||||||
dt
|
|
||||||
)
|
|
||||||
dt.apply {
|
dt.apply {
|
||||||
hasContent =
|
hasContent =
|
||||||
false
|
false
|
||||||
|
@ -377,6 +376,10 @@ fun QuizScreen(
|
||||||
false
|
false
|
||||||
data = "?"
|
data = "?"
|
||||||
}
|
}
|
||||||
|
quizViewModel.updateQuestionShuffled(
|
||||||
|
ind,
|
||||||
|
newDt
|
||||||
|
)
|
||||||
checkNull = true
|
checkNull = true
|
||||||
quizXOffset[id] =
|
quizXOffset[id] =
|
||||||
0f
|
0f
|
||||||
|
@ -431,6 +434,7 @@ fun QuizScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println("--------")
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.example.lexilearn.ui.views.pQuiz
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.speech.tts.TextToSpeech
|
import android.speech.tts.TextToSpeech
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
@ -46,10 +45,6 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
||||||
_indexQuiz.value += 1
|
_indexQuiz.value += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadNewQuestion(material: MaterialDataModel, questionMode: Int, answerMode: Int) {
|
|
||||||
_currentQuestion.value = quizRepository.generateQuestion(material, questionMode, answerMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _shuffledAnswerLetters = MutableStateFlow<List<ModelAnswer>>(emptyList())
|
private val _shuffledAnswerLetters = MutableStateFlow<List<ModelAnswer>>(emptyList())
|
||||||
val shuffledAnswerLetters: StateFlow<List<ModelAnswer>> = _shuffledAnswerLetters
|
val shuffledAnswerLetters: StateFlow<List<ModelAnswer>> = _shuffledAnswerLetters
|
||||||
|
|
||||||
|
@ -101,7 +96,7 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
||||||
val listAnswer =
|
val listAnswer =
|
||||||
_currentQuestion.value?.correctAnswer?.correctWord?.mapIndexed { index, char ->
|
_currentQuestion.value?.correctAnswer?.correctWord?.mapIndexed { index, char ->
|
||||||
ModelAnswer(
|
ModelAnswer(
|
||||||
id = (_indexQuiz.value * 100) + index + 1, // ID unik per pertanyaan
|
id = (_indexQuiz.value * 100) + index + 1,
|
||||||
data = char.toString().lowercase()
|
data = char.toString().lowercase()
|
||||||
)
|
)
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
|
@ -135,24 +130,21 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkAnswer(answerString: String): Boolean {
|
fun checkAnswer(answerString: String): Boolean {
|
||||||
if (answerString.lowercase() == currentQuestion.value?.correctAnswer?.correctWord?.lowercase()) {
|
return (answerString.lowercase() == currentQuestion.value?.correctAnswer?.correctWord?.lowercase())
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun observeData() {
|
fun observeData() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_questionShuffled.collect { newList ->
|
_questionShuffled.collect { newList ->
|
||||||
// Lakukan aksi setiap kali data berubah
|
|
||||||
var answerString = ""
|
var answerString = ""
|
||||||
newList.forEach { text ->
|
newList.forEach { text ->
|
||||||
answerString = answerString + text.data
|
answerString = answerString + text.data
|
||||||
}
|
}
|
||||||
if (answerString.contains("?") || answerString.isEmpty() || answerString.contains("null")) {
|
if (answerString.contains("?") || answerString.isEmpty() || answerString.contains("null")) {
|
||||||
|
println("if-$answerString")
|
||||||
_isButtonVisible.value = false
|
_isButtonVisible.value = false
|
||||||
} else {
|
} else {
|
||||||
Log.d("cobaaja", answerString)
|
println("else-$answerString")
|
||||||
val checkData = checkAnswer(answerString);
|
val checkData = checkAnswer(answerString);
|
||||||
if (checkData) {
|
if (checkData) {
|
||||||
triggerSnackbar("Jawaban Benar")
|
triggerSnackbar("Jawaban Benar")
|
||||||
|
@ -185,6 +177,8 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// competition
|
||||||
|
|
||||||
private val _totalScore = MutableStateFlow(0)
|
private val _totalScore = MutableStateFlow(0)
|
||||||
val totalScore: StateFlow<Int> get() = _totalScore.asStateFlow()
|
val totalScore: StateFlow<Int> get() = _totalScore.asStateFlow()
|
||||||
|
|
||||||
|
@ -288,12 +282,11 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
||||||
val penaltyTime = max(0, responseTime - safeTime) * timePenalty
|
val penaltyTime = max(0, responseTime - safeTime) * timePenalty
|
||||||
val penaltyWrong = wrongAttempts * wrongPenalty
|
val penaltyWrong = wrongAttempts * wrongPenalty
|
||||||
var score = baseScore - penaltyTime - penaltyWrong
|
var score = baseScore - penaltyTime - penaltyWrong
|
||||||
|
if (responseTime <= 5) {
|
||||||
if (responseTime <= 3) {
|
// println("responset: $responseTime")
|
||||||
score += bonusQuick
|
score += bonusQuick
|
||||||
}
|
}
|
||||||
|
|
||||||
return max(minScore, score)
|
return max(minScore, score)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
Loading…
Reference in New Issue