view image fix
This commit is contained in:
parent
a6ea1d5ce0
commit
2b8aadfc73
|
|
@ -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()) }
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -212,61 +267,4 @@ class AddProfileViewModel(
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue