update user repository
This commit is contained in:
parent
97c22c5325
commit
8a328e7dd4
|
@ -14,7 +14,7 @@ import androidx.navigation.compose.rememberNavController
|
|||
import androidx.navigation.navArgument
|
||||
import com.example.lexilearn.data.model.MaterialDataModel
|
||||
import com.example.lexilearn.data.model.UserDataModel
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.UserRepository
|
||||
import com.example.lexilearn.ui.views.pDetailMaterial.DetailMaterialScreen
|
||||
import com.example.lexilearn.ui.views.pHome.HomeScreen
|
||||
import com.example.lexilearn.ui.views.pLearAlphabet.LearnAlphabetScreen
|
||||
|
@ -34,10 +34,10 @@ import com.example.lexilearn.ui.views.pSplashcreen.SplashScreen
|
|||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val repository = MaterialRepository(this)
|
||||
val userRepository = UserRepository(this)
|
||||
|
||||
// 🔥 Coba login
|
||||
repository.loginUser{ success, userId ->
|
||||
userRepository.loginUser{ success, userId ->
|
||||
if (success) {
|
||||
Toast.makeText(this, "Login Berhasil! ID: $userId", Toast.LENGTH_SHORT).show()
|
||||
Log.d("MainActivity", "Login Berhasil! User ID: $userId")
|
||||
|
@ -51,14 +51,14 @@ class MainActivity : ComponentActivity() {
|
|||
unlock_data = UserDataModel.UnlockData()
|
||||
)
|
||||
|
||||
repository.createUser(newUser) { success, newUserId ->
|
||||
userRepository.createUser(newUser) { success, newUserId ->
|
||||
if (success) {
|
||||
Toast.makeText(
|
||||
this,
|
||||
"User Baru Dibuat! Login Sekarang...",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
repository.loginUser { loginSuccess, loggedInUserId ->
|
||||
userRepository.loginUser { loginSuccess, loggedInUserId ->
|
||||
if (loginSuccess) {
|
||||
Log.d(
|
||||
"MainActivity",
|
||||
|
|
|
@ -6,224 +6,25 @@ import com.example.lexilearn.data.remote.FirebaseHelper
|
|||
import com.example.lexilearn.data.model.MaterialDataModel
|
||||
import com.example.lexilearn.data.model.UserDataModel
|
||||
import com.google.firebase.database.FirebaseDatabase
|
||||
|
||||
class MaterialRepository(private val context: Context) {
|
||||
private val sharedPrefHelper = SharedPrefHelper(context)
|
||||
private val firebaseHelper = FirebaseHelper(context)
|
||||
|
||||
fun getMaterialData(filterMaterial: String, callback: (List<MaterialDataModel>) -> Unit) {
|
||||
val cachedData =
|
||||
sharedPrefHelper.getMaterialList(filterMaterial) // Ambil data dengan filter
|
||||
if (cachedData != null) {
|
||||
callback(cachedData)
|
||||
} else {
|
||||
firebaseHelper.fetchMaterials(filterMaterial) { materials ->
|
||||
sharedPrefHelper.saveMaterialList(
|
||||
filterMaterial,
|
||||
materials
|
||||
)
|
||||
callback(materials)
|
||||
}
|
||||
sharedPrefHelper.getMaterialList(filterMaterial)?.let {
|
||||
callback(it)
|
||||
} ?: firebaseHelper.fetchMaterials(filterMaterial) { materials ->
|
||||
sharedPrefHelper.saveMaterialList(filterMaterial, materials)
|
||||
callback(materials)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllMaterialData(filterMaterial: String, callback: (List<MaterialDataModel>) -> Unit) {
|
||||
val cachedData =
|
||||
sharedPrefHelper.getMaterialList(filterMaterial) // Ambil data dengan filter
|
||||
if (cachedData != null) {
|
||||
callback(cachedData)
|
||||
} else {
|
||||
firebaseHelper.fetchAllMaterials { materials ->
|
||||
sharedPrefHelper.saveMaterialList(
|
||||
filterMaterial,
|
||||
materials
|
||||
)
|
||||
callback(materials)
|
||||
}
|
||||
sharedPrefHelper.getMaterialList(filterMaterial)?.let {
|
||||
callback(it)
|
||||
} ?: firebaseHelper.fetchAllMaterials { materials ->
|
||||
sharedPrefHelper.saveMaterialList(filterMaterial, materials)
|
||||
callback(materials)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUser(updatedUser: UserDataModel, callback: (Boolean) -> Unit) {
|
||||
firebaseHelper.updateUser(updatedUser, callback)
|
||||
}
|
||||
|
||||
fun createUser(user: UserDataModel, callback: (Boolean, String?) -> Unit) {
|
||||
firebaseHelper.createUser(user, callback)
|
||||
}
|
||||
|
||||
fun loginUser( callback: (Boolean, String?) -> Unit) {
|
||||
firebaseHelper.loginUser{ success, userId ->
|
||||
if (success && userId != null) {
|
||||
sharedPrefHelper.saveUserId(userId) // Simpan ID user
|
||||
callback(true, userId)
|
||||
} else {
|
||||
callback(false, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserData(callback: (UserDataModel?) -> Unit) {
|
||||
firebaseHelper.fetchUserData { user ->
|
||||
callback(user)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUnlockData(idUnlock: String, value: Int, callback: (Boolean) -> Unit) {
|
||||
try {
|
||||
val userId = sharedPrefHelper.getUserId()
|
||||
if (userId == null) {
|
||||
println("printUpdateUnlock: userId is null")
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||
|
||||
// Ambil data user dari Firebase dengan try-catch di dalam callback
|
||||
userRef.get().addOnSuccessListener { snapshot ->
|
||||
try {
|
||||
val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
||||
|
||||
// Hanya update jika nilai baru lebih besar
|
||||
if (value > currentValue) {
|
||||
userRef.setValue(value).addOnCompleteListener { task ->
|
||||
try {
|
||||
if (task.isSuccessful) {
|
||||
// Update juga di SharedPreferences
|
||||
val updatedUser = sharedPrefHelper.getUserData()
|
||||
updatedUser?.unlock_data?.let { unlockData ->
|
||||
when (idUnlock) {
|
||||
"animal" -> unlockData.animal = value
|
||||
"family" -> unlockData.family = value
|
||||
"house" -> unlockData.house = value
|
||||
"limb" -> unlockData.limb = value
|
||||
}
|
||||
}
|
||||
// Pastikan updatedUser tidak null sebelum menyimpan
|
||||
if (updatedUser != null) {
|
||||
println("printUpdateUnlock: successfully updated Firebase and SharedPreferences")
|
||||
sharedPrefHelper.saveUserData(updatedUser)
|
||||
callback(true)
|
||||
} else {
|
||||
println("printUpdateUnlock: updatedUser is null after updating Firebase")
|
||||
callback(false)
|
||||
}
|
||||
} else {
|
||||
println("printUpdateUnlock: task is not successful")
|
||||
callback(false)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
println("printUpdateUnlock: exception in onCompleteListener: $e")
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("printUpdateUnlock: new value $value is not greater than current value $currentValue")
|
||||
callback(false) // Jika nilai baru <= nilai lama, tidak update
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
println("printUpdateUnlock: exception in onSuccessListener: $e")
|
||||
callback(false)
|
||||
}
|
||||
}.addOnFailureListener {
|
||||
it.printStackTrace()
|
||||
println("printUpdateUnlock: failed to get data: ${it.message}")
|
||||
callback(false)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
println("printUpdateUnlock: error_update_unlock_data: $e")
|
||||
e.printStackTrace()
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
||||
// fun updateUnlockData(idUnlock: String, value: Int, callback: (Boolean) -> Unit) {
|
||||
// try {
|
||||
// val userId = sharedPrefHelper.getUserId()
|
||||
// if (userId == null) {
|
||||
// callback(false)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||
//
|
||||
// // Ambil data user dari Firebase dengan try-catch di dalam callback
|
||||
// userRef.get().addOnSuccessListener { snapshot ->
|
||||
// try {
|
||||
// val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
||||
//
|
||||
// // Hanya update jika nilai baru lebih besar
|
||||
// if (value > currentValue) {
|
||||
// userRef.setValue(value).addOnCompleteListener { task ->
|
||||
// try {
|
||||
// if (task.isSuccessful) {
|
||||
// // Update juga di SharedPreferences
|
||||
// val updatedUser = sharedPrefHelper.getUserData()
|
||||
// updatedUser?.unlock_data?.let { unlockData ->
|
||||
// when (idUnlock) {
|
||||
// "animal" -> unlockData.animal = value
|
||||
// "family" -> unlockData.family = value
|
||||
// "house" -> unlockData.house = value
|
||||
// "limb" -> unlockData.limb = value
|
||||
// }
|
||||
// }
|
||||
// // Pastikan updatedUser tidak null sebelum menyimpan
|
||||
// if (updatedUser != null) {
|
||||
// sharedPrefHelper.saveUserData(updatedUser)
|
||||
// callback(true)
|
||||
// } else {
|
||||
// callback(false)
|
||||
// }
|
||||
// } else {
|
||||
// callback(false)
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// callback(false)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// callback(false) // Jika nilai baru <= nilai lama, tidak update
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// callback(false)
|
||||
// }
|
||||
// }.addOnFailureListener {
|
||||
// it.printStackTrace()
|
||||
// callback(false)
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// println("error_update_unlock_data: $e")
|
||||
// e.printStackTrace()
|
||||
// callback(false)
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
fun getUnlockValue(idUnlock: String, callback: (Int?) -> Unit) {
|
||||
val userId = sharedPrefHelper.getUserId()
|
||||
|
||||
if (userId == null) {
|
||||
callback(null)
|
||||
return
|
||||
}
|
||||
|
||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||
|
||||
// 🔥 Ambil nilai dari Firebase
|
||||
userRef.get().addOnSuccessListener { snapshot ->
|
||||
val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
||||
callback(currentValue)
|
||||
}.addOnFailureListener {
|
||||
callback(null) // 🔥 Gagal mengambil data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun logoutUser() {
|
||||
sharedPrefHelper.clearUserData()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package com.example.lexilearn.data.repository
|
||||
|
||||
import android.content.Context
|
||||
import com.example.lexilearn.data.local.SharedPrefHelper
|
||||
import com.example.lexilearn.data.model.UserDataModel
|
||||
import com.example.lexilearn.data.remote.FirebaseHelper
|
||||
import com.google.firebase.database.FirebaseDatabase
|
||||
|
||||
class UserRepository(private val context: Context) {
|
||||
private val sharedPrefHelper = SharedPrefHelper(context)
|
||||
private val firebaseHelper = FirebaseHelper(context)
|
||||
|
||||
fun updateUser(updatedUser: UserDataModel, callback: (Boolean) -> Unit) {
|
||||
firebaseHelper.updateUser(updatedUser, callback)
|
||||
}
|
||||
|
||||
fun createUser(user: UserDataModel, callback: (Boolean, String?) -> Unit) {
|
||||
firebaseHelper.createUser(user, callback)
|
||||
}
|
||||
|
||||
fun loginUser(callback: (Boolean, String?) -> Unit) {
|
||||
firebaseHelper.loginUser { success, userId ->
|
||||
if (success && userId != null) {
|
||||
sharedPrefHelper.saveUserId(userId)
|
||||
callback(true, userId)
|
||||
} else {
|
||||
callback(false, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserData(callback: (UserDataModel?) -> Unit) {
|
||||
firebaseHelper.fetchUserData(callback)
|
||||
}
|
||||
|
||||
fun updateUnlockData(idUnlock: String, value: Int, callback: (Boolean) -> Unit) {
|
||||
val userId = sharedPrefHelper.getUserId() ?: run {
|
||||
println("printUpdateUnlock: userId is null")
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||
|
||||
userRef.get().addOnSuccessListener { snapshot ->
|
||||
val currentValue = snapshot.getValue(Int::class.java) ?: 0
|
||||
if (value > currentValue) {
|
||||
userRef.setValue(value).addOnCompleteListener { task ->
|
||||
if (task.isSuccessful) {
|
||||
sharedPrefHelper.getUserData()?.let { updatedUser ->
|
||||
updatedUser.unlock_data?.apply {
|
||||
when (idUnlock) {
|
||||
"animal" -> animal = value
|
||||
"family" -> family = value
|
||||
"house" -> house = value
|
||||
"limb" -> limb = value
|
||||
}
|
||||
}
|
||||
sharedPrefHelper.saveUserData(updatedUser)
|
||||
println("printUpdateUnlock: successfully updated Firebase and SharedPreferences")
|
||||
callback(true)
|
||||
} ?: run {
|
||||
println("printUpdateUnlock: updatedUser is null after updating Firebase")
|
||||
callback(false)
|
||||
}
|
||||
} else {
|
||||
println("printUpdateUnlock: task is not successful")
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("printUpdateUnlock: new value $value is not greater than current value $currentValue")
|
||||
callback(false)
|
||||
}
|
||||
}.addOnFailureListener {
|
||||
println("printUpdateUnlock: failed to get data: ${it.message}")
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
||||
fun getUnlockValue(idUnlock: String, callback: (Int?) -> Unit) {
|
||||
val userId = sharedPrefHelper.getUserId()
|
||||
if (userId == null) {
|
||||
callback(null)
|
||||
return
|
||||
}
|
||||
|
||||
val userRef = FirebaseDatabase.getInstance().getReference("users/$userId/unlock_data/$idUnlock")
|
||||
userRef.get().addOnSuccessListener { snapshot ->
|
||||
callback(snapshot.getValue(Int::class.java) ?: 0)
|
||||
}.addOnFailureListener {
|
||||
callback(null)
|
||||
}
|
||||
}
|
||||
|
||||
fun logoutUser() {
|
||||
sharedPrefHelper.clearUserData()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package com.example.lexilearn.domain.models
|
||||
|
||||
data class ModelAnswerRead (
|
||||
data class ModelAnswer (
|
||||
var id: Int,
|
||||
var data: String,
|
||||
var showCard: Boolean = true,
|
|
@ -1,6 +1,6 @@
|
|||
package com.example.lexilearn.domain.models
|
||||
|
||||
data class ModelSpell(
|
||||
data class ModelQuestion(
|
||||
val id: Int,
|
||||
val type: Boolean,
|
||||
var data: String,
|
|
@ -12,10 +12,10 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.lexilearn.data.model.UserDataModel
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.UserRepository
|
||||
|
||||
@Composable
|
||||
fun DialogProfile(showDialog: Boolean, repository: MaterialRepository, userData: UserDataModel, onDismiss: () -> Unit) {
|
||||
fun DialogProfile(showDialog: Boolean, repository: UserRepository, userData: UserDataModel, onDismiss: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
var name by remember { mutableStateOf(TextFieldValue(userData.name)) }
|
||||
var age by remember { mutableStateOf(TextFieldValue(userData.age.toString())) }
|
||||
|
|
|
@ -8,7 +8,6 @@ import androidx.lifecycle.MutableLiveData
|
|||
import com.example.lexilearn.data.model.MaterialDataModel
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.QuizRepository
|
||||
import com.example.lexilearn.domain.models.ModelSpell
|
||||
import com.example.lexilearn.utils.generateNumberList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
|
@ -421,7 +421,7 @@ fun HomeScreen(navController: NavController, viewModel: HomeViewModel = viewMode
|
|||
if(userData.value!=null){
|
||||
DialogProfile(
|
||||
showDialog = showDialogProfile.value,
|
||||
repository = viewModel.materialRepository,
|
||||
repository = viewModel.userRepository,
|
||||
userData = userData.value!!
|
||||
) {
|
||||
viewModel.showHiddenDialog()
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.example.lexilearn.data.model.MaterialDataModel
|
|||
import com.example.lexilearn.data.model.UserDataModel
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.QuizRepository
|
||||
import com.example.lexilearn.data.repository.UserRepository
|
||||
import com.google.firebase.database.DataSnapshot
|
||||
import com.google.firebase.database.DatabaseError
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
|
@ -28,6 +29,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
|||
private val totalDataCompetition = 3
|
||||
|
||||
val materialRepository = MaterialRepository(application)
|
||||
val userRepository = UserRepository(application)
|
||||
private val _quizRepository = QuizRepository()
|
||||
|
||||
private val _dialogProfile = MutableStateFlow<Boolean>(false)
|
||||
|
@ -57,7 +59,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
|||
fun getUserData() {
|
||||
viewModelScope.launch {
|
||||
delay(3000)
|
||||
materialRepository.getUserData { data ->
|
||||
userRepository.getUserData { data ->
|
||||
_userData.value = data
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.lifecycle.MutableLiveData
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.lexilearn.data.model.MaterialDataModel
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.UserRepository
|
||||
import com.example.lexilearn.utils.generateNumberList
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -33,13 +34,14 @@ class NavMaterialViewModel(application: Application) : AndroidViewModel(applicat
|
|||
val navLockPosition: StateFlow<Int> = _navLockPosition
|
||||
|
||||
private val repository = MaterialRepository(application)
|
||||
private val userRepository = UserRepository(application)
|
||||
|
||||
private val _materialList = MutableStateFlow<List<List<MaterialDataModel>>>(emptyList())
|
||||
val materialList: StateFlow<List<List<MaterialDataModel>>> = _materialList
|
||||
|
||||
fun fetchMaterial(materialId: String) {
|
||||
viewModelScope.launch {
|
||||
repository.getUnlockValue(materialId) { value ->
|
||||
userRepository.getUnlockValue(materialId) { value ->
|
||||
_sizeUnlock.value = value
|
||||
}
|
||||
repository.getMaterialData(materialId) { materials ->
|
||||
|
@ -80,7 +82,7 @@ class NavMaterialViewModel(application: Application) : AndroidViewModel(applicat
|
|||
fun updateUnlockValue(materialId: String, value: Int) {
|
||||
if(value >= (_sizeUnlock.value ?: 0) && _materialList.value.size > value){
|
||||
viewModelScope.launch {
|
||||
repository.updateUnlockData(materialId, value){
|
||||
userRepository.updateUnlockData(materialId, value){
|
||||
println("numberUnlock update unlock value success $it")
|
||||
fetchMaterial(materialId)
|
||||
}
|
||||
|
|
|
@ -11,10 +11,9 @@ import androidx.lifecycle.MutableLiveData
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.lexilearn.data.model.MaterialDataModel
|
||||
import com.example.lexilearn.data.model.QuizQuestion
|
||||
import com.example.lexilearn.data.model.QuizState
|
||||
import com.example.lexilearn.data.repository.QuizRepository
|
||||
import com.example.lexilearn.domain.models.ModelAnswerRead
|
||||
import com.example.lexilearn.domain.models.ModelSpell
|
||||
import com.example.lexilearn.domain.models.ModelAnswer
|
||||
import com.example.lexilearn.domain.models.ModelQuestion
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -51,17 +50,17 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
_currentQuestion.value = quizRepository.generateQuestion(material, questionMode, answerMode)
|
||||
}
|
||||
|
||||
private val _shuffledAnswerLetters = MutableStateFlow<List<ModelAnswerRead>>(emptyList())
|
||||
val shuffledAnswerLetters: StateFlow<List<ModelAnswerRead>> = _shuffledAnswerLetters
|
||||
private val _shuffledAnswerLetters = MutableStateFlow<List<ModelAnswer>>(emptyList())
|
||||
val shuffledAnswerLetters: StateFlow<List<ModelAnswer>> = _shuffledAnswerLetters
|
||||
|
||||
|
||||
private val _questionShuffled = MutableStateFlow<List<ModelSpell>>(emptyList())
|
||||
val questionShuffled: StateFlow<List<ModelSpell>> = _questionShuffled
|
||||
private val _questionShuffled = MutableStateFlow<List<ModelQuestion>>(emptyList())
|
||||
val questionShuffled: StateFlow<List<ModelQuestion>> = _questionShuffled
|
||||
|
||||
private val _isButtonVisible = mutableStateOf(false)
|
||||
val isButtonVisible: State<Boolean> get() = _isButtonVisible
|
||||
|
||||
fun updateQuestionShuffled(index: Int, newData: ModelSpell) {
|
||||
fun updateQuestionShuffled(index: Int, newData: ModelQuestion) {
|
||||
_questionShuffled.value = _questionShuffled.value.mapIndexed { i, item ->
|
||||
if (i == index) {
|
||||
item.copy(
|
||||
|
@ -90,7 +89,7 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
|
||||
val dataQuest =
|
||||
_currentQuestion.value?.correctAnswer?.correctWord?.mapIndexed { index, char ->
|
||||
ModelSpell(
|
||||
ModelQuestion(
|
||||
id = (_indexQuiz.value * 100) + index + 1,
|
||||
type = true,
|
||||
data = "?",
|
||||
|
@ -101,9 +100,9 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
|
||||
val listAnswer =
|
||||
_currentQuestion.value?.correctAnswer?.correctWord?.mapIndexed { index, char ->
|
||||
ModelAnswerRead(
|
||||
ModelAnswer(
|
||||
id = (_indexQuiz.value * 100) + index + 1, // ID unik per pertanyaan
|
||||
data = char.toString()
|
||||
data = char.toString().lowercase()
|
||||
)
|
||||
} ?: emptyList()
|
||||
_shuffledAnswerLetters.value = listAnswer.shuffled()
|
||||
|
@ -186,91 +185,6 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
super.onCleared()
|
||||
}
|
||||
|
||||
// competition ====================================================================
|
||||
// private val _quizState = MutableLiveData<QuizState>()
|
||||
// val quizState: LiveData<QuizState> get() = _quizState
|
||||
//
|
||||
// private val _currentScore = MutableLiveData(0) // Skor untuk soal saat ini
|
||||
// val currentScore: LiveData<Int> get() = _currentScore
|
||||
//
|
||||
// private val _totalScore = MutableLiveData(0) // Total skor sepanjang sesi
|
||||
// val totalScore: LiveData<Int> get() = _totalScore
|
||||
//
|
||||
// private var questionList = listOf<MaterialDataModel>()
|
||||
// private var currentQuestionIndex = 0
|
||||
// private var wrongAttempts = 0
|
||||
// private var startTime: Long = 0
|
||||
//
|
||||
// // Konstanta untuk scoring
|
||||
// private val baseScore = 100
|
||||
// private val safeTime = 5
|
||||
// private val timePenalty = 3
|
||||
// private val wrongPenalty = 5
|
||||
// private val minScore = 50
|
||||
// private val bonusQuick = 10
|
||||
//
|
||||
// /** 1️⃣ Memulai Kuis **/
|
||||
// fun startQuiz(materials: List<MaterialDataModel>) {
|
||||
// if (materials.isNotEmpty()) {
|
||||
// questionList = materials
|
||||
// currentQuestionIndex = 0
|
||||
// _totalScore.value = 0 // Reset skor saat mulai
|
||||
// _currentScore.value = 0
|
||||
// wrongAttempts = 0
|
||||
// startTime = System.currentTimeMillis()
|
||||
// _quizState.value =
|
||||
// QuizState.QuestionLoaded(questionList[currentQuestionIndex], _totalScore.value ?: 0)
|
||||
// } else {
|
||||
// _quizState.value = QuizState.Error("Tidak ada soal tersedia")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /** 2️⃣ Dipanggil saat jawaban dikirim **/
|
||||
// fun submitAnswer(isCorrect: Boolean) {
|
||||
// val responseTime =
|
||||
// ((System.currentTimeMillis() - startTime) / 1000).toInt() // Hitung waktu otomatis
|
||||
//
|
||||
// if (isCorrect) {
|
||||
// val score = calculateScore(responseTime, wrongAttempts)
|
||||
// _currentScore.value = score
|
||||
// _totalScore.value = (_totalScore.value ?: 0) + score // Update total skor
|
||||
// moveToNextQuestion()
|
||||
// } else {
|
||||
// wrongAnswer()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /** 3️⃣ Dipanggil saat jawaban salah **/
|
||||
// fun wrongAnswer() {
|
||||
// wrongAttempts += 1
|
||||
// _quizState.value = QuizState.AnswerWrong(wrongAttempts)
|
||||
// }
|
||||
//
|
||||
// /** 4️⃣ Berganti ke soal berikutnya **/
|
||||
// private fun moveToNextQuestion() {
|
||||
// if (currentQuestionIndex < questionList.size - 1) {
|
||||
// currentQuestionIndex++
|
||||
// wrongAttempts = 0
|
||||
// startTime = System.currentTimeMillis()
|
||||
// _quizState.value =
|
||||
// QuizState.QuestionLoaded(questionList[currentQuestionIndex], _totalScore.value ?: 0)
|
||||
// } else {
|
||||
// _quizState.value = QuizState.QuizFinished(_totalScore.value ?: 0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /** 🔢 Perhitungan Skor **/
|
||||
// private fun calculateScore(responseTime: Int, wrongAttempts: Int): Int {
|
||||
// val penaltyTime = maxOf(0, responseTime - safeTime) * timePenalty
|
||||
// val penaltyWrong = wrongAttempts * wrongPenalty
|
||||
// var score = baseScore - penaltyTime - penaltyWrong
|
||||
//
|
||||
// if (responseTime <= 3) {
|
||||
// score += bonusQuick
|
||||
// }
|
||||
//
|
||||
// return maxOf(minScore, score)
|
||||
// }
|
||||
private val _totalScore = MutableStateFlow(0)
|
||||
val totalScore: StateFlow<Int> get() = _totalScore.asStateFlow()
|
||||
|
||||
|
@ -323,7 +237,8 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
while (isRunning) {
|
||||
val elapsedTime = System.currentTimeMillis() - startTime
|
||||
_responseTimeMs.value = elapsedTime // Stopwatch berjalan
|
||||
_liveCurrentScore.value = calculateRealTimeScore((elapsedTime / 1000).toInt(), wrongAttempts)
|
||||
_liveCurrentScore.value =
|
||||
calculateRealTimeScore((elapsedTime / 1000).toInt(), wrongAttempts)
|
||||
_formattedResponseTime.value = String.format("%.1f", elapsedTime / 1000.0)
|
||||
delay(100) // Update setiap 100ms
|
||||
}
|
||||
|
@ -350,7 +265,8 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
/** Saat jawaban salah **/
|
||||
fun wrongAnswer() {
|
||||
wrongAttempts += 1
|
||||
_liveCurrentScore.value = calculateRealTimeScore((_responseTimeMs.value / 1000).toInt(), wrongAttempts)
|
||||
_liveCurrentScore.value =
|
||||
calculateRealTimeScore((_responseTimeMs.value / 1000).toInt(), wrongAttempts)
|
||||
}
|
||||
|
||||
/** Berganti ke soal berikutnya **/
|
||||
|
@ -362,7 +278,7 @@ class QuizViewModel(application: Application) : AndroidViewModel(application),
|
|||
_scoreReduction.value = baseScore // Reset ke 100
|
||||
_liveCurrentScore.value = baseScore
|
||||
startStopwatch() // Restart stopwatch
|
||||
}else{
|
||||
} else {
|
||||
_finalScore.value = _totalScore.value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ import androidx.compose.ui.unit.sp
|
|||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.navigation.NavController
|
||||
import com.example.lexilearn.R
|
||||
import com.example.lexilearn.domain.models.ModelAnswerRead
|
||||
import com.example.lexilearn.domain.models.ModelAnswer
|
||||
import com.example.lexilearn.domain.models.ModelWords
|
||||
import com.example.lexilearn.ui.components.ButtonNext
|
||||
import com.example.lexilearn.ui.components.CardQuiz
|
||||
|
@ -85,9 +85,9 @@ fun ReadScreen(navController: NavController) {
|
|||
val listAnswer =
|
||||
remember {
|
||||
mutableStateListOf(
|
||||
ModelAnswerRead(1, "chases"),
|
||||
ModelAnswerRead(2, "run"),
|
||||
ModelAnswerRead(3, "watches")
|
||||
ModelAnswer(1, "chases"),
|
||||
ModelAnswer(2, "run"),
|
||||
ModelAnswer(3, "watches")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.navigation.NavController
|
||||
import com.example.lexilearn.domain.models.ModelAnswerRead
|
||||
import com.example.lexilearn.domain.models.ModelAnswer
|
||||
import com.example.lexilearn.ui.components.CardQuiz
|
||||
import com.example.lexilearn.ui.components.DraggableAnswerCard
|
||||
import com.example.lexilearn.ui.components.GradientQuiz
|
||||
|
@ -47,7 +47,7 @@ import com.example.lexilearn.ui.components.MyShadowCard
|
|||
import com.example.lexilearn.ui.theme.ctextWhite
|
||||
import kotlin.math.roundToInt
|
||||
import com.example.lexilearn.R
|
||||
import com.example.lexilearn.domain.models.ModelSpell
|
||||
import com.example.lexilearn.domain.models.ModelQuestion
|
||||
import com.example.lexilearn.ui.components.ButtonNext
|
||||
import com.example.lexilearn.ui.theme.ctextGray
|
||||
|
||||
|
@ -66,20 +66,20 @@ fun SpellScreen(navController: NavController) {
|
|||
|
||||
var dataQuiz = remember {
|
||||
mutableStateListOf(
|
||||
ModelSpell(1, false, "r ", showCard = false),
|
||||
ModelSpell(2, false, "i", showCard = false),
|
||||
ModelSpell(3, true, "?", showCard = false),
|
||||
ModelSpell(4, false, "e", showCard = false),
|
||||
ModelQuestion(1, false, "r ", showCard = false),
|
||||
ModelQuestion(2, false, "i", showCard = false),
|
||||
ModelQuestion(3, true, "?", showCard = false),
|
||||
ModelQuestion(4, false, "e", showCard = false),
|
||||
)
|
||||
}
|
||||
|
||||
val listAnswer =
|
||||
remember {
|
||||
mutableStateListOf(
|
||||
ModelAnswerRead(1, "a"),
|
||||
ModelAnswerRead(2, "c"),
|
||||
ModelAnswerRead(3, "d"),
|
||||
ModelAnswerRead(4, "k")
|
||||
ModelAnswer(1, "a"),
|
||||
ModelAnswer(2, "c"),
|
||||
ModelAnswer(3, "d"),
|
||||
ModelAnswer(4, "k")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import DrawBox
|
|||
import android.graphics.Bitmap
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
@ -13,27 +12,18 @@ import androidx.compose.foundation.layout.Spacer
|
|||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateMapOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.boundsInWindow
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.Font
|
||||
|
@ -43,18 +33,14 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
import androidx.navigation.NavController
|
||||
import com.example.lexilearn.R
|
||||
import com.example.lexilearn.domain.models.ModelAnswerRead
|
||||
import com.example.lexilearn.domain.models.ModelSpell
|
||||
import com.example.lexilearn.domain.models.ModelQuestion
|
||||
import com.example.lexilearn.ui.components.AutoSizeText
|
||||
import com.example.lexilearn.ui.components.ButtonNext
|
||||
import com.example.lexilearn.ui.components.CardQuiz
|
||||
import com.example.lexilearn.ui.components.CustomButton
|
||||
import com.example.lexilearn.ui.components.GradientQuiz
|
||||
import com.example.lexilearn.ui.components.MyShadowCard
|
||||
import com.example.lexilearn.ui.theme.ctextBlack
|
||||
import com.example.lexilearn.ui.theme.ctextGray
|
||||
import com.example.lexilearn.ui.theme.ctextWhite
|
||||
|
||||
|
@ -70,10 +56,10 @@ fun WriteScreen(navController: NavController) {
|
|||
|
||||
var dataQuiz = remember {
|
||||
mutableStateListOf(
|
||||
ModelSpell(1, false, "r ", showCard = false),
|
||||
ModelSpell(2, false, "i", showCard = false),
|
||||
ModelSpell(3, true, "?", showCard = false),
|
||||
ModelSpell(4, false, "e", showCard = false),
|
||||
ModelQuestion(1, false, "r ", showCard = false),
|
||||
ModelQuestion(2, false, "i", showCard = false),
|
||||
ModelQuestion(3, true, "?", showCard = false),
|
||||
ModelQuestion(4, false, "e", showCard = false),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.lifecycle.AndroidViewModel
|
|||
import com.example.lexilearn.data.model.CompetitionScore
|
||||
import com.example.lexilearn.data.repository.MaterialRepository
|
||||
import com.example.lexilearn.data.repository.QuizRepository
|
||||
import com.example.lexilearn.data.repository.UserRepository
|
||||
import com.google.firebase.database.DataSnapshot
|
||||
import com.google.firebase.database.DatabaseError
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
|
@ -21,6 +22,7 @@ import java.util.UUID
|
|||
class ResultScreeningViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private val database: DatabaseReference = FirebaseDatabase.getInstance().getReference("competitions")
|
||||
private val materialRepo = MaterialRepository(application)
|
||||
private val userRepository = UserRepository(application)
|
||||
|
||||
private val _positionScore = MutableStateFlow(0)
|
||||
val positionScore: StateFlow<Int> = _positionScore
|
||||
|
@ -32,7 +34,7 @@ class ResultScreeningViewModel(application: Application) : AndroidViewModel(appl
|
|||
|
||||
fun submitScore(score: Int) {
|
||||
|
||||
materialRepo.getUserData {dataUser->
|
||||
userRepository.getUserData {dataUser->
|
||||
val todayDate = getTodayDate()
|
||||
val dateRef = database.child(todayDate)
|
||||
|
||||
|
|
Loading…
Reference in New Issue