From 80d2100ce3e6237679a5f0f737416923a6fa6f16 Mon Sep 17 00:00:00 2001 From: omer358 Date: Tue, 2 Jul 2024 02:24:06 +0400 Subject: [PATCH] fix the update feature there was an bug in the update feature, it creates a new user instead of updating the existing one, on top of that I created a use case for updating the person --- .../com/example/rememberme/di/AppModule.kt | 4 +- .../domain/usecases/people/PeopleUseCases.kt | 3 +- .../domain/usecases/people/UpdatePerson.kt | 17 +++ .../presentation/addperson/AddPersonScreen.kt | 8 +- .../addperson/AddPersonUiState.kt | 15 +-- .../addperson/AddPersonViewModel.kt | 111 ++++++++++-------- 6 files changed, 94 insertions(+), 64 deletions(-) create mode 100644 app/src/main/java/com/example/rememberme/domain/usecases/people/UpdatePerson.kt diff --git a/app/src/main/java/com/example/rememberme/di/AppModule.kt b/app/src/main/java/com/example/rememberme/di/AppModule.kt index 8ca94ee..0f555e0 100644 --- a/app/src/main/java/com/example/rememberme/di/AppModule.kt +++ b/app/src/main/java/com/example/rememberme/di/AppModule.kt @@ -15,6 +15,7 @@ import com.example.rememberme.domain.usecases.people.GetAllPeople import com.example.rememberme.domain.usecases.people.GetPersonById import com.example.rememberme.domain.usecases.people.InsertNewPerson import com.example.rememberme.domain.usecases.people.PeopleUseCases +import com.example.rememberme.domain.usecases.people.UpdatePerson import com.example.rememberme.utils.Constants.PEOPLE_DATABASE_NAME import com.example.remindme.database.PeopleDao import dagger.Module @@ -62,7 +63,8 @@ object AppModule { return PeopleUseCases( getAllPeople = GetAllPeople(peopleRepository), getPersonById = GetPersonById(peopleRepository), - insertPerson = InsertNewPerson(peopleRepository) + insertPerson = InsertNewPerson(peopleRepository), + updatePerson = UpdatePerson(peopleRepository) ) } diff --git a/app/src/main/java/com/example/rememberme/domain/usecases/people/PeopleUseCases.kt b/app/src/main/java/com/example/rememberme/domain/usecases/people/PeopleUseCases.kt index 76cdffb..a1914a4 100644 --- a/app/src/main/java/com/example/rememberme/domain/usecases/people/PeopleUseCases.kt +++ b/app/src/main/java/com/example/rememberme/domain/usecases/people/PeopleUseCases.kt @@ -3,5 +3,6 @@ package com.example.rememberme.domain.usecases.people data class PeopleUseCases( val getAllPeople: GetAllPeople, val getPersonById: GetPersonById, - val insertPerson: InsertNewPerson + val insertPerson: InsertNewPerson, + val updatePerson: UpdatePerson ) \ No newline at end of file diff --git a/app/src/main/java/com/example/rememberme/domain/usecases/people/UpdatePerson.kt b/app/src/main/java/com/example/rememberme/domain/usecases/people/UpdatePerson.kt new file mode 100644 index 0000000..231bfed --- /dev/null +++ b/app/src/main/java/com/example/rememberme/domain/usecases/people/UpdatePerson.kt @@ -0,0 +1,17 @@ +package com.example.rememberme.domain.usecases.people + +import android.util.Log +import com.example.rememberme.domain.model.People +import com.example.rememberme.domain.repository.PeopleRepository + +class UpdatePerson( + private val peopleRepository: PeopleRepository +) { + suspend operator fun invoke(person: People) { + Log.i(TAG,"UpdatePersonUseCase: invoked") + peopleRepository.updatePeople(person) + } + companion object { + private const val TAG = "UpdatePerson" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonScreen.kt b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonScreen.kt index 00de389..cb53392 100644 --- a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonScreen.kt +++ b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonScreen.kt @@ -72,7 +72,7 @@ fun AddPersonScreen( popUp: () -> Unit, personId: Long? ) { - val uiState = viewModel.uiState.collectAsState().value + val uiState by viewModel.uiState.collectAsState() val isPersonSaved by viewModel.isPersonSaved.collectAsState() val sheetState = rememberModalBottomSheetState() @@ -93,8 +93,10 @@ fun AddPersonScreen( LaunchedEffect(personId) { if (personId != null) { + Log.i(TAG,"LoadPersonDetails on the addPerson screen") viewModel.loadPersonDetails(personId) } else { + Log.i(TAG,"creating new person screen") viewModel.resetForm() } } @@ -209,7 +211,6 @@ fun AddPersonContent( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically ) { - Log.i(TAG, "AddPersonContent: $selectedAvatarResId") Image( painter = painterResource(id = selectedAvatarResId), contentDescription = null, @@ -229,12 +230,13 @@ fun AddPersonContent( Spacer(modifier = Modifier.size(16.dp)) CustomButton( onClick = onSavePerson, - text = "Save" + text = if (uiState.id != null) "Update" else "Save" ) } } } + @Composable fun DateTimePicker( initialDateTime: String, diff --git a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonUiState.kt b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonUiState.kt index 9abdf2e..202b6f7 100644 --- a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonUiState.kt +++ b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonUiState.kt @@ -3,16 +3,17 @@ package com.example.rememberme.presentation.addperson import com.example.rememberme.R data class AddPersonUiState( + val id: Long? = null, val firstName: String = "", - val firstNameError: String? = null, val secondName: String = "", - val secondNameError: String? = null, val place: String = "", - val placeError: String? = null, val time: String = "", - val timeError: String? = null, val note: String? = null, val gender: String = "", - val genderError: String? = null, - val avatar: Int = R.drawable.ic_f1, -) \ No newline at end of file + val avatar: Int = R.drawable.ic_m1, + val firstNameError: String? = null, + val secondNameError: String? = null, + val placeError: String? = null, + val timeError: String? = null, + val genderError: String? = null +) diff --git a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonViewModel.kt b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonViewModel.kt index e889d0c..1c3cc80 100644 --- a/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonViewModel.kt +++ b/app/src/main/java/com/example/rememberme/presentation/addperson/AddPersonViewModel.kt @@ -19,6 +19,7 @@ class AddPersonViewModel @Inject constructor( private val peopleUseCases: PeopleUseCases, private val addPersonUseCases: AddPersonUseCases ) : ViewModel() { + private val _uiState = MutableStateFlow(AddPersonUiState()) val uiState: StateFlow = _uiState @@ -28,59 +29,44 @@ class AddPersonViewModel @Inject constructor( fun onEvent(event: AddPersonEvents) { when (event) { is AddPersonEvents.OnFirstNameChange -> { - Log.i(TAG, "onEvent: OnFirstNameChange -> ${event.firstName}") - _uiState.value = - _uiState.value.copy(firstName = event.firstName, firstNameError = null) + _uiState.value = _uiState.value.copy(firstName = event.firstName, firstNameError = null) } - is AddPersonEvents.OnSecondNameChange -> { - Log.i(TAG, "onEvent: OnSecondNameChange -> ${event.secondName}") - _uiState.value = - _uiState.value.copy(secondName = event.secondName, secondNameError = null) + _uiState.value = _uiState.value.copy(secondName = event.secondName, secondNameError = null) } - is AddPersonEvents.OnPlaceChange -> { - Log.i(TAG, "onEvent: OnPlaceChange -> ${event.place}") _uiState.value = _uiState.value.copy(place = event.place, placeError = null) } - is AddPersonEvents.OnTimeChange -> { - Log.i(TAG, "onEvent: OnTimeChange -> ${event.time}") _uiState.value = _uiState.value.copy(time = event.time) } - is AddPersonEvents.OnNoteChange -> { - Log.i(TAG, "onEvent: OnNoteChange -> ${event.note}") _uiState.value = _uiState.value.copy(note = event.note) } - is AddPersonEvents.OnGenderChange -> { - Log.i(TAG, "onEvent: OnGenderChange -> ${event.gender}") _uiState.value = _uiState.value.copy(gender = event.gender, genderError = null) } - is AddPersonEvents.OnAvatarChange -> { - - Log.i(TAG, "onEvent: OnAvatarChange -> ${event.avatar}") _uiState.value = _uiState.value.copy(avatar = event.avatar) } - AddPersonEvents.OnSavePerson -> { - Log.i(TAG, "onEvent: OnSavePerson") - savePerson() + if (_uiState.value.id != null) { + updatePerson() + } else { + savePerson() + } } } } fun loadPersonDetails(personId: Long) { - Log.i(TAG, "loadPersonDetails: $personId") viewModelScope.launch { withContext(Dispatchers.IO) { val person = peopleUseCases.getPersonById(personId) person.collect { person -> if (person != null) { - Log.i(TAG, "loadPersonDetails: $person") _uiState.value = _uiState.value.copy( + id = person.id, firstName = person.firstName, secondName = person.secondName, place = person.place, @@ -89,27 +75,67 @@ class AddPersonViewModel @Inject constructor( time = person.time, note = person.note, ) - Log.i(TAG, "loadPersonDetails: ${_uiState.value}") } } } } } - fun resetForm() { - Log.i(TAG, "resetForm: ") _uiState.value = AddPersonUiState() } private fun savePerson() { + if (validateInput()) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + val person = People( + firstName = _uiState.value.firstName, + secondName = _uiState.value.secondName, + place = _uiState.value.place, + time = _uiState.value.time, + note = _uiState.value.note, + gender = _uiState.value.gender, + avatar = _uiState.value.avatar + ) + peopleUseCases.insertPerson(person) + } + _isPersonSaved.value = true + } + } + } + + private fun updatePerson() { + if (validateInput()) { + Log.i(TAG,"validateInput on update: input are valid!") + viewModelScope.launch { + withContext(Dispatchers.IO) { + val person :People = _uiState.value.id?.let { + People( + id = it, + firstName = _uiState.value.firstName, + secondName = _uiState.value.secondName, + place = _uiState.value.place, + time = _uiState.value.time, + note = _uiState.value.note, + gender = _uiState.value.gender, + avatar = _uiState.value.avatar + ) + }!! + peopleUseCases.updatePerson(person) + } + _isPersonSaved.value = true + } + } + } + + private fun validateInput(): Boolean { val firstNameResult = addPersonUseCases.validateFirstNameUseCase(_uiState.value.firstName) - val secondNameResult = - addPersonUseCases.validateSecondNameUseCase(_uiState.value.secondName) + val secondNameResult = addPersonUseCases.validateSecondNameUseCase(_uiState.value.secondName) val placeResult = addPersonUseCases.validatePlaceUseCase(_uiState.value.place) val timeResult = addPersonUseCases.validateTimeUseCase(_uiState.value.time) val genderResult = addPersonUseCases.validateGenderSelectionUseCase(_uiState.value.gender) - Log.d(TAG, "savePerson: $genderResult") + val hasError = listOf( firstNameResult, secondNameResult, @@ -117,9 +143,8 @@ class AddPersonViewModel @Inject constructor( timeResult, genderResult ).any { !it.successful } + if (hasError) { - Log.e(TAG, "savePerson: There are some unvalidated inputs") - Log.e(TAG, "savePerson: ${_uiState.value}") _uiState.value = _uiState.value.copy( firstNameError = firstNameResult.errorMessage, secondNameError = secondNameResult.errorMessage, @@ -128,30 +153,12 @@ class AddPersonViewModel @Inject constructor( genderError = genderResult.errorMessage ) _isPersonSaved.value = false - - } else { - viewModelScope.launch { - withContext(Dispatchers.IO) { - Log.i(TAG, "savePerson: ${_uiState.value}") - val person = People( - firstName = _uiState.value.firstName, - secondName = _uiState.value.secondName, - place = _uiState.value.place, - time = _uiState.value.time, - note = _uiState.value.note, - gender = _uiState.value.gender, - avatar = _uiState.value.avatar - ) - peopleUseCases.insertPerson(person) - } - _isPersonSaved.value = true - - } + return false } + return true } companion object { private const val TAG = "AddPersonViewModel" } - -} \ No newline at end of file +}