This commit is contained in:
DimazzP 2025-05-03 23:24:06 +07:00
parent 8a328e7dd4
commit 9f049952e8
12 changed files with 127 additions and 135 deletions

View File

@ -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
}
} }
} }
} }

View File

@ -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 =

View File

@ -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,

View File

@ -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 {

View File

@ -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
)
*/
) )

View File

@ -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
) )

View File

@ -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 }
} }

View File

@ -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(

View File

@ -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"

View File

@ -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))
} }

View File

@ -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.