view image fix

This commit is contained in:
SaiD 2025-12-20 20:41:29 +05:30
parent a6ea1d5ce0
commit 2b8aadfc73
3 changed files with 96 additions and 108 deletions

View File

@ -181,7 +181,7 @@ val appModule = module {
viewModel { HomeViewModel(get()) } viewModel { HomeViewModel(get()) }
viewModel { OnBoardingViewModel(get()) } viewModel { OnBoardingViewModel(get()) }
viewModel { (savedStateHandle: androidx.lifecycle.SavedStateHandle?) -> viewModel { (savedStateHandle: androidx.lifecycle.SavedStateHandle?) ->
AddProfileViewModel(get(), get(), androidContext(), savedStateHandle) AddProfileViewModel(get(), get(), savedStateHandle)
} }
viewModel { ListingsViewModel(get()) } viewModel { ListingsViewModel(get()) }
viewModel { SettingsViewModel(get()) } viewModel { SettingsViewModel(get()) }

View File

@ -47,8 +47,6 @@ import com.example.livingai.utils.Constants
fun AddProfileScreen( fun AddProfileScreen(
navController: NavController, navController: NavController,
viewModel: AddProfileViewModel, viewModel: AddProfileViewModel,
animalId: String?,
loadEntry: Boolean,
onSave: () -> Unit, onSave: () -> Unit,
onCancel: () -> Unit, onCancel: () -> Unit,
onTakePhoto: (String) -> Unit, onTakePhoto: (String) -> Unit,
@ -56,14 +54,6 @@ fun AddProfileScreen(
) { ) {
val context = LocalContext.current val context = LocalContext.current
LaunchedEffect(animalId, loadEntry) {
if (loadEntry && animalId != null) {
viewModel.loadAnimal(animalId)
} else {
viewModel.initializeNewProfile()
}
}
val speciesList = stringArrayResource(id = R.array.species_list).toList() val speciesList = stringArrayResource(id = R.array.species_list).toList()
val breedList = stringArrayResource(id = R.array.cow_breed_list).toList() val breedList = stringArrayResource(id = R.array.cow_breed_list).toList()

View File

@ -1,8 +1,5 @@
package com.example.livingai.pages.addprofile package com.example.livingai.pages.addprofile
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -10,9 +7,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.livingai.domain.model.AnimalDetails import com.example.livingai.domain.model.AnimalDetails
import com.example.livingai.domain.usecases.GetAnimalDetails
import com.example.livingai.domain.usecases.ProfileEntry.ProfileEntryUseCase import com.example.livingai.domain.usecases.ProfileEntry.ProfileEntryUseCase
import com.example.livingai.utils.Constants
import com.example.livingai.utils.CoroutineDispatchers import com.example.livingai.utils.CoroutineDispatchers
import com.example.livingai.utils.IdGenerator import com.example.livingai.utils.IdGenerator
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -23,17 +18,19 @@ import kotlinx.coroutines.withContext
class AddProfileViewModel( class AddProfileViewModel(
private val profileEntryUseCase: ProfileEntryUseCase, private val profileEntryUseCase: ProfileEntryUseCase,
private val dispatchers: CoroutineDispatchers, private val dispatchers: CoroutineDispatchers,
private val context: Context, private val savedStateHandle: SavedStateHandle? = null
val savedStateHandle: SavedStateHandle? = null
) : ViewModel() { ) : ViewModel() {
private val _animalDetails = mutableStateOf<AnimalDetails?>(null) companion object {
val animalDetails: State<AnimalDetails?> = _animalDetails private const val KEY_ANIMAL_ID = "animal_id"
}
private val _currentAnimalId = mutableStateOf<String?>(null) private val _animalDetails = mutableStateOf<AnimalDetails?>(null)
private val _currentAnimalId =
mutableStateOf(savedStateHandle?.get<String>(KEY_ANIMAL_ID))
val currentAnimalId: State<String?> = _currentAnimalId val currentAnimalId: State<String?> = _currentAnimalId
// UI State
var species = mutableStateOf<String?>(null) var species = mutableStateOf<String?>(null)
var breed = mutableStateOf<String?>(null) var breed = mutableStateOf<String?>(null)
var age = mutableStateOf("") var age = mutableStateOf("")
@ -42,7 +39,6 @@ class AddProfileViewModel(
var reproductiveStatus = mutableStateOf<String?>(null) var reproductiveStatus = mutableStateOf<String?>(null)
var description = mutableStateOf("") var description = mutableStateOf("")
// Errors
var ageError = mutableStateOf<String?>(null) var ageError = mutableStateOf<String?>(null)
var milkYieldError = mutableStateOf<String?>(null) var milkYieldError = mutableStateOf<String?>(null)
var calvingNumberError = mutableStateOf<String?>(null) var calvingNumberError = mutableStateOf<String?>(null)
@ -50,31 +46,50 @@ class AddProfileViewModel(
var breedError = mutableStateOf<String?>(null) var breedError = mutableStateOf<String?>(null)
var reproductiveStatusError = mutableStateOf<String?>(null) var reproductiveStatusError = mutableStateOf<String?>(null)
// Save state
private val _saveSuccess = mutableStateOf(false) private val _saveSuccess = mutableStateOf(false)
val saveSuccess: State<Boolean> = _saveSuccess
// State for photos and video
val photos = mutableStateMapOf<String, String>() val photos = mutableStateMapOf<String, String>()
val segmentedImages = mutableStateMapOf<String, String>() val segmentedImages = mutableStateMapOf<String, String>()
private val _videoUri = mutableStateOf<String?>(null) private val _videoUri = mutableStateOf<String?>(null)
val videoUri: State<String?> = _videoUri val videoUri: State<String?> = _videoUri
fun initializeNewProfileIfNeeded() {
if (_currentAnimalId.value != null) return
val id = IdGenerator.generateAnimalId()
_currentAnimalId.value = id
savedStateHandle?.let { it[KEY_ANIMAL_ID] = id }
_animalDetails.value = null
species.value = null
breed.value = null
age.value = ""
milkYield.value = ""
calvingNumber.value = ""
reproductiveStatus.value = null
description.value = ""
clearErrors()
photos.clear()
segmentedImages.clear()
_videoUri.value = null
}
fun loadAnimal(animalId: String) { fun loadAnimal(animalId: String) {
if (animalId == _currentAnimalId.value) return if (_currentAnimalId.value == animalId) return
_currentAnimalId.value = animalId _currentAnimalId.value = animalId
savedStateHandle?.set(KEY_ANIMAL_ID, animalId)
profileEntryUseCase.getAnimalDetails(animalId)
.onEach { details ->
details ?: return@onEach
profileEntryUseCase.getAnimalDetails(animalId).onEach { details ->
if (details != null) {
_animalDetails.value = details _animalDetails.value = details
// Populate UI State
species.value = details.species.ifBlank { null } species.value = details.species.ifBlank { null }
breed.value = details.breed.ifBlank { null } breed.value = details.breed.ifBlank { null }
age.value = if (details.age == 0) "" else details.age.toString() age.value = details.age.takeIf { it > 0 }?.toString() ?: ""
milkYield.value = if (details.milkYield == 0) "" else details.milkYield.toString() milkYield.value = details.milkYield.takeIf { it > 0 }?.toString() ?: ""
calvingNumber.value = if (details.calvingNumber == 0) "" else details.calvingNumber.toString() calvingNumber.value = details.calvingNumber.takeIf { it > 0 }?.toString() ?: ""
reproductiveStatus.value = details.reproductiveStatus.ifBlank { null } reproductiveStatus.value = details.reproductiveStatus.ifBlank { null }
description.value = details.description description.value = details.description
clearErrors() clearErrors()
@ -83,16 +98,43 @@ class AddProfileViewModel(
segmentedImages.clear() segmentedImages.clear()
withContext(dispatchers.main) { withContext(dispatchers.main) {
details.images.entries.forEach { (orientation, path) -> details.images.forEach { photos[it.key] = it.value }
photos[orientation] = path details.segmentedImages.forEach { segmentedImages[it.key] = it.value }
}
details.segmentedImages.entries.forEach { (orientation, path) ->
segmentedImages[orientation] = path
}
} }
_videoUri.value = details.video.ifBlank { null } _videoUri.value = details.video.ifBlank { null }
} }
}.launchIn(viewModelScope) .launchIn(viewModelScope)
}
fun saveAnimalDetails(): Boolean {
if (!validateInputs()) return false
val id = _currentAnimalId.value ?: return false
val details = AnimalDetails(
animalId = id,
species = species.value ?: "",
breed = breed.value ?: "",
age = age.value.toIntOrNull() ?: 0,
milkYield = milkYield.value.toIntOrNull() ?: 0,
calvingNumber = calvingNumber.value.toIntOrNull() ?: 0,
reproductiveStatus = reproductiveStatus.value ?: "",
description = description.value,
images = photos,
video = _videoUri.value ?: "",
segmentedImages = segmentedImages,
name = "",
sex = "",
weight = 0
)
viewModelScope.launch {
profileEntryUseCase.setAnimalDetails(details)
_saveSuccess.value = true
}
return true
} }
private fun clearErrors() { private fun clearErrors() {
@ -116,6 +158,19 @@ class AddProfileViewModel(
_videoUri.value = uri _videoUri.value = uri
} }
private fun validateInputs(): Boolean {
var isValid = true
if (!validateSpeciesInputs()) isValid = false
if (!validateBreedInputs()) isValid = false
if (!validateAgeInputs()) isValid = false
if (!validateMilkYieldInputs()) isValid = false
if (!validateCalvingInputs()) isValid = false
if (!validateReproductiveStatusInputs()) isValid = false
return isValid
}
fun validateSpeciesInputs(s: String? = null): Boolean { fun validateSpeciesInputs(s: String? = null): Boolean {
if (s != null) if (s != null)
species.value = s species.value = s
@ -207,66 +262,9 @@ class AddProfileViewModel(
calvingNumberError.value = "Invalid calving number" calvingNumberError.value = "Invalid calving number"
isValid = false isValid = false
} else { } else {
calvingNumberError.value = null calvingNumberError.value = null
} }
return isValid return isValid
} }
private fun validateInputs(): Boolean {
return validateSpeciesInputs() && validateBreedInputs() && validateAgeInputs()
&& validateMilkYieldInputs() && validateCalvingInputs() && validateReproductiveStatusInputs()
}
fun saveAnimalDetails(): Boolean {
if (!validateInputs()) return false
val id = _currentAnimalId.value ?: IdGenerator.generateAnimalId().also { _currentAnimalId.value = it }
val details = AnimalDetails(
animalId = id,
species = species.value ?: "",
breed = breed.value ?: "",
age = age.value.toIntOrNull() ?: 0,
milkYield = milkYield.value.toIntOrNull() ?: 0,
calvingNumber = calvingNumber.value.toIntOrNull() ?: 0,
reproductiveStatus = reproductiveStatus.value ?: "",
description = description.value,
images = photos,
video = _videoUri.value ?: "",
segmentedImages = segmentedImages,
name = "", sex = "", weight = 0
)
viewModelScope.launch {
profileEntryUseCase.setAnimalDetails(details)
_saveSuccess.value = true
}
return true
}
fun onSaveComplete() {
_saveSuccess.value = false
}
fun initializeNewProfile() {
val newId = IdGenerator.generateAnimalId()
_currentAnimalId.value = newId
_animalDetails.value = null
// Reset UI State
species.value = null
breed.value = null
age.value = ""
milkYield.value = ""
calvingNumber.value = ""
reproductiveStatus.value = null
description.value = ""
clearErrors()
photos.clear()
segmentedImages.clear()
_videoUri.value = null
}
} }