AI:remove more boilerplate

This commit is contained in:
androidlover5842
2026-02-03 09:38:30 +05:30
parent d6c8e522de
commit 4e5f368256
8 changed files with 115 additions and 96 deletions

View File

@@ -2,9 +2,12 @@ package com.android.trisolarispms.core.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.data.api.core.ApiService
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.Response
internal fun <S> ViewModel.launchRequest(
state: MutableStateFlow<S>,
@@ -23,3 +26,31 @@ internal fun <S> ViewModel.launchRequest(
}
}
}
internal fun <S> ViewModel.launchApiMutation(
state: MutableStateFlow<S>,
action: String,
setLoading: (S) -> S,
setSuccess: (S) -> S,
setError: (S, String) -> S,
onDone: () -> Unit = {},
createApi: () -> ApiService = { ApiClient.create() },
call: suspend (ApiService) -> Response<*>
) {
launchRequest(
state = state,
setLoading = setLoading,
setError = setError,
defaultError = "$action failed"
) {
val response = call(createApi())
if (response.isSuccessful) {
state.update(setSuccess)
onDone()
} else {
state.update { current ->
setError(current, "$action failed: ${response.code()}")
}
}
}
}

View File

@@ -1,15 +1,13 @@
package com.android.trisolarispms.ui.room
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.core.viewmodel.launchApiMutation
import com.android.trisolarispms.data.api.core.ApiService
import com.android.trisolarispms.data.api.model.RoomCreateRequest
import com.android.trisolarispms.data.api.model.RoomUpdateRequest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.Response
class RoomFormViewModel : ViewModel() {
@@ -146,19 +144,14 @@ class RoomFormViewModel : ViewModel() {
onDone: () -> Unit,
call: suspend (ApiService) -> Response<*>
) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true, error = null) }
try {
val response = call(ApiClient.create())
if (response.isSuccessful) {
_state.update { it.copy(isLoading = false, success = true) }
onDone()
} else {
_state.update { it.copy(isLoading = false, error = "$action failed: ${response.code()}") }
}
} catch (e: Exception) {
_state.update { it.copy(isLoading = false, error = e.localizedMessage ?: "$action failed") }
}
}
launchApiMutation(
state = _state,
action = action,
setLoading = { it.copy(isLoading = true, error = null) },
setSuccess = { it.copy(isLoading = false, success = true) },
setError = { current, message -> current.copy(isLoading = false, error = message) },
onDone = onDone,
call = call
)
}
}

View File

@@ -1,9 +1,6 @@
package com.android.trisolarispms.ui.roomimage
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
@@ -12,18 +9,12 @@ fun AddImageTagScreen(
onSave: () -> Unit,
viewModel: ImageTagFormViewModel = viewModel()
) {
val state by viewModel.state.collectAsState()
LaunchedEffect(Unit) {
viewModel.reset()
}
ImageTagFormScreen(
ImageTagEditorScreen(
title = "Add Tag",
name = state.name,
error = state.error,
onNameChange = viewModel::onNameChange,
setupKey = Unit,
onBack = onBack,
onSave = { viewModel.submitCreate(onSave) }
onSaveClick = { viewModel.submitCreate(onSave) },
setupForm = { viewModel.reset() },
viewModel = viewModel
)
}

View File

@@ -1,9 +1,6 @@
package com.android.trisolarispms.ui.roomimage
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.trisolarispms.data.api.model.RoomImageTagDto
@@ -14,18 +11,12 @@ fun EditImageTagScreen(
onSave: () -> Unit,
viewModel: ImageTagFormViewModel = viewModel()
) {
val state by viewModel.state.collectAsState()
LaunchedEffect(tag.id) {
viewModel.setTag(tag)
}
ImageTagFormScreen(
ImageTagEditorScreen(
title = "Edit Tag",
name = state.name,
error = state.error,
onNameChange = viewModel::onNameChange,
setupKey = tag.id,
onBack = onBack,
onSave = { viewModel.submitUpdate(tag.id.orEmpty(), onSave) }
onSaveClick = { viewModel.submitUpdate(tag.id.orEmpty(), onSave) },
setupForm = { viewModel.setTag(tag) },
viewModel = viewModel
)
}

View File

@@ -0,0 +1,31 @@
package com.android.trisolarispms.ui.roomimage
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@Composable
internal fun ImageTagEditorScreen(
title: String,
setupKey: Any?,
onBack: () -> Unit,
onSaveClick: () -> Unit,
setupForm: () -> Unit,
viewModel: ImageTagFormViewModel
) {
val state by viewModel.state.collectAsState()
LaunchedEffect(setupKey) {
setupForm()
}
ImageTagFormScreen(
title = title,
name = state.name,
error = state.error,
onNameChange = viewModel::onNameChange,
onBack = onBack,
onSave = onSaveClick
)
}

View File

@@ -1,14 +1,12 @@
package com.android.trisolarispms.ui.roomimage
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.core.viewmodel.launchApiMutation
import com.android.trisolarispms.data.api.core.ApiService
import com.android.trisolarispms.data.api.model.RoomImageTagDto
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.Response
class ImageTagFormViewModel : ViewModel() {
@@ -64,22 +62,17 @@ class ImageTagFormViewModel : ViewModel() {
resetOnSuccess: Boolean,
call: suspend (ApiService) -> Response<*>
) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true, error = null) }
try {
val response = call(ApiClient.create())
if (response.isSuccessful) {
_state.update {
launchApiMutation(
state = _state,
action = action,
setLoading = { it.copy(isLoading = true, error = null) },
setSuccess = {
if (resetOnSuccess) ImageTagFormState(success = true)
else it.copy(isLoading = false, success = true)
}
onDone()
} else {
_state.update { it.copy(isLoading = false, error = "$action failed: ${response.code()}") }
}
} catch (e: Exception) {
_state.update { it.copy(isLoading = false, error = e.localizedMessage ?: "$action failed") }
}
}
},
setError = { current, message -> current.copy(isLoading = false, error = message) },
onDone = onDone,
call = call
)
}
}

View File

@@ -2,6 +2,7 @@ package com.android.trisolarispms.ui.roomtype
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.trisolarispms.core.viewmodel.launchApiMutation
import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.data.api.core.ApiService
import com.android.trisolarispms.data.api.model.AmenityCreateRequest
@@ -147,19 +148,14 @@ class AmenityFormViewModel : ViewModel() {
onDone: () -> Unit,
call: suspend (ApiService) -> Response<*>
) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true, error = null) }
try {
val response = call(ApiClient.create())
if (response.isSuccessful) {
_state.update { it.copy(isLoading = false, success = true) }
onDone()
} else {
_state.update { it.copy(isLoading = false, error = "$action failed: ${response.code()}") }
}
} catch (e: Exception) {
_state.update { it.copy(isLoading = false, error = e.localizedMessage ?: "$action failed") }
}
}
launchApiMutation(
state = _state,
action = action,
setLoading = { it.copy(isLoading = true, error = null) },
setSuccess = { it.copy(isLoading = false, success = true) },
setError = { current, message -> current.copy(isLoading = false, error = message) },
onDone = onDone,
call = call
)
}
}

View File

@@ -1,15 +1,13 @@
package com.android.trisolarispms.ui.roomtype
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.core.viewmodel.launchApiMutation
import com.android.trisolarispms.data.api.core.ApiService
import com.android.trisolarispms.data.api.model.RoomTypeCreateRequest
import com.android.trisolarispms.data.api.model.RoomTypeUpdateRequest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.Response
class RoomTypeFormViewModel : ViewModel() {
@@ -144,19 +142,14 @@ class RoomTypeFormViewModel : ViewModel() {
onDone: () -> Unit,
call: suspend (ApiService) -> Response<*>
) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true, error = null) }
try {
val response = call(ApiClient.create())
if (response.isSuccessful) {
_state.update { it.copy(isLoading = false, success = true) }
onDone()
} else {
_state.update { it.copy(isLoading = false, error = "$action failed: ${response.code()}") }
}
} catch (e: Exception) {
_state.update { it.copy(isLoading = false, error = e.localizedMessage ?: "$action failed") }
}
}
launchApiMutation(
state = _state,
action = action,
setLoading = { it.copy(isLoading = true, error = null) },
setSuccess = { it.copy(isLoading = false, success = true) },
setError = { current, message -> current.copy(isLoading = false, error = message) },
onDone = onDone,
call = call
)
}
}