From 8a328e7dd4766f0fdfa52b55527fb41e2bbf104f Mon Sep 17 00:00:00 2001 From: DimazzP Date: Wed, 5 Mar 2025 21:34:53 +0700 Subject: [PATCH] update user repository --- .../com/example/lexilearn/MainActivity.kt | 10 +- .../data/repository/MaterialRepository.kt | 221 +----------------- .../data/repository/UserRepository.kt | 99 ++++++++ .../{ModelAnswerRead.kt => ModelAnswer.kt} | 2 +- .../{ModelSpell.kt => ModelQuestion.kt} | 2 +- .../lexilearn/ui/components/DialogProfile.kt | 4 +- .../DetailMaterialViewModel.kt | 1 - .../lexilearn/ui/views/pHome/HomeScreen.kt | 2 +- .../lexilearn/ui/views/pHome/HomeViewModel.kt | 4 +- .../pNavMaterial/NavMaterialViewModel.kt | 6 +- .../lexilearn/ui/views/pQuiz/QuizViewModel.kt | 114 ++------- .../ui/views/pQuiz/pRead/ReadScreen.kt | 8 +- .../ui/views/pQuiz/pSpell/SpellScreen.kt | 20 +- .../ui/views/pQuiz/pWrite/WriteScreen.kt | 24 +- .../ResultScreeningViewModel.kt | 4 +- 15 files changed, 164 insertions(+), 357 deletions(-) create mode 100644 app/src/main/java/com/example/lexilearn/data/repository/UserRepository.kt rename app/src/main/java/com/example/lexilearn/domain/models/{ModelAnswerRead.kt => ModelAnswer.kt} (80%) rename app/src/main/java/com/example/lexilearn/domain/models/{ModelSpell.kt => ModelQuestion.kt} (88%) diff --git a/app/src/main/java/com/example/lexilearn/MainActivity.kt b/app/src/main/java/com/example/lexilearn/MainActivity.kt index 34caa95..fc66079 100644 --- a/app/src/main/java/com/example/lexilearn/MainActivity.kt +++ b/app/src/main/java/com/example/lexilearn/MainActivity.kt @@ -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", diff --git a/app/src/main/java/com/example/lexilearn/data/repository/MaterialRepository.kt b/app/src/main/java/com/example/lexilearn/data/repository/MaterialRepository.kt index c7f29de..d8ec14a 100644 --- a/app/src/main/java/com/example/lexilearn/data/repository/MaterialRepository.kt +++ b/app/src/main/java/com/example/lexilearn/data/repository/MaterialRepository.kt @@ -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) -> 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) -> 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() - } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/lexilearn/data/repository/UserRepository.kt b/app/src/main/java/com/example/lexilearn/data/repository/UserRepository.kt new file mode 100644 index 0000000..2bb0b4a --- /dev/null +++ b/app/src/main/java/com/example/lexilearn/data/repository/UserRepository.kt @@ -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() + } +} diff --git a/app/src/main/java/com/example/lexilearn/domain/models/ModelAnswerRead.kt b/app/src/main/java/com/example/lexilearn/domain/models/ModelAnswer.kt similarity index 80% rename from app/src/main/java/com/example/lexilearn/domain/models/ModelAnswerRead.kt rename to app/src/main/java/com/example/lexilearn/domain/models/ModelAnswer.kt index bc8761d..8d9a2d0 100644 --- a/app/src/main/java/com/example/lexilearn/domain/models/ModelAnswerRead.kt +++ b/app/src/main/java/com/example/lexilearn/domain/models/ModelAnswer.kt @@ -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, diff --git a/app/src/main/java/com/example/lexilearn/domain/models/ModelSpell.kt b/app/src/main/java/com/example/lexilearn/domain/models/ModelQuestion.kt similarity index 88% rename from app/src/main/java/com/example/lexilearn/domain/models/ModelSpell.kt rename to app/src/main/java/com/example/lexilearn/domain/models/ModelQuestion.kt index 6bc167a..d064b2f 100644 --- a/app/src/main/java/com/example/lexilearn/domain/models/ModelSpell.kt +++ b/app/src/main/java/com/example/lexilearn/domain/models/ModelQuestion.kt @@ -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, diff --git a/app/src/main/java/com/example/lexilearn/ui/components/DialogProfile.kt b/app/src/main/java/com/example/lexilearn/ui/components/DialogProfile.kt index 3ed318b..48e1200 100644 --- a/app/src/main/java/com/example/lexilearn/ui/components/DialogProfile.kt +++ b/app/src/main/java/com/example/lexilearn/ui/components/DialogProfile.kt @@ -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())) } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pDetailMaterial/DetailMaterialViewModel.kt b/app/src/main/java/com/example/lexilearn/ui/views/pDetailMaterial/DetailMaterialViewModel.kt index d084d89..118756c 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pDetailMaterial/DetailMaterialViewModel.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pDetailMaterial/DetailMaterialViewModel.kt @@ -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 diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeScreen.kt b/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeScreen.kt index 4de1b9b..37cd88e 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeScreen.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeScreen.kt @@ -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() diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeViewModel.kt b/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeViewModel.kt index f7edfe0..fd8969b 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeViewModel.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pHome/HomeViewModel.kt @@ -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(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 } } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pNavMaterial/NavMaterialViewModel.kt b/app/src/main/java/com/example/lexilearn/ui/views/pNavMaterial/NavMaterialViewModel.kt index 2a02464..969b852 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pNavMaterial/NavMaterialViewModel.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pNavMaterial/NavMaterialViewModel.kt @@ -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 = _navLockPosition private val repository = MaterialRepository(application) + private val userRepository = UserRepository(application) private val _materialList = MutableStateFlow>>(emptyList()) val materialList: StateFlow>> = _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) } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/QuizViewModel.kt b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/QuizViewModel.kt index a25c08d..4557ef5 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/QuizViewModel.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/QuizViewModel.kt @@ -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>(emptyList()) - val shuffledAnswerLetters: StateFlow> = _shuffledAnswerLetters + private val _shuffledAnswerLetters = MutableStateFlow>(emptyList()) + val shuffledAnswerLetters: StateFlow> = _shuffledAnswerLetters - private val _questionShuffled = MutableStateFlow>(emptyList()) - val questionShuffled: StateFlow> = _questionShuffled + private val _questionShuffled = MutableStateFlow>(emptyList()) + val questionShuffled: StateFlow> = _questionShuffled private val _isButtonVisible = mutableStateOf(false) val isButtonVisible: State 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() -// val quizState: LiveData get() = _quizState -// -// private val _currentScore = MutableLiveData(0) // Skor untuk soal saat ini -// val currentScore: LiveData get() = _currentScore -// -// private val _totalScore = MutableLiveData(0) // Total skor sepanjang sesi -// val totalScore: LiveData get() = _totalScore -// -// private var questionList = listOf() -// 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) { -// 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 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 } } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pRead/ReadScreen.kt b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pRead/ReadScreen.kt index 31b1283..d36b41e 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pRead/ReadScreen.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pRead/ReadScreen.kt @@ -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") ) } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pSpell/SpellScreen.kt b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pSpell/SpellScreen.kt index db2cfc6..147450c 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pSpell/SpellScreen.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pSpell/SpellScreen.kt @@ -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") ) } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pWrite/WriteScreen.kt b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pWrite/WriteScreen.kt index b1ccd4b..d18aa49 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pWrite/WriteScreen.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pQuiz/pWrite/WriteScreen.kt @@ -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), ) } diff --git a/app/src/main/java/com/example/lexilearn/ui/views/pResultScreening/ResultScreeningViewModel.kt b/app/src/main/java/com/example/lexilearn/ui/views/pResultScreening/ResultScreeningViewModel.kt index 135b283..e074cbc 100644 --- a/app/src/main/java/com/example/lexilearn/ui/views/pResultScreening/ResultScreeningViewModel.kt +++ b/app/src/main/java/com/example/lexilearn/ui/views/pResultScreening/ResultScreeningViewModel.kt @@ -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 = _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)