implement refreshing instances in viewmodel and accordingly in ui

This commit is contained in:
Minecon724 2024-07-31 15:53:59 +02:00
parent c10484f698
commit f4b3760d84
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8
4 changed files with 77 additions and 14 deletions

View file

@ -1,6 +1,7 @@
package eu.m724.vastapp.activity.dashboard
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
@ -14,11 +15,16 @@ import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
@ -34,8 +40,11 @@ import eu.m724.vastapp.activity.dashboard.screen.InstancesScreen
import eu.m724.vastapp.ui.theme.VastappTheme
import eu.m724.vastapp.vastai.VastApi
import eu.m724.vastapp.vastai.data.User
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors
import kotlin.coroutines.coroutineContext
class DashboardActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -49,6 +58,17 @@ class DashboardActivity : ComponentActivity() {
val dashboardViewModel = DashboardViewModel(user, vastApi)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
dashboardViewModel.refreshError.collect {
it.forEach { errorMsg ->
Toast.makeText(baseContext, errorMsg, Toast.LENGTH_SHORT).show()
}
}
}
}
enableEdgeToEdge()
setContent {
VastappTheme {

View file

@ -1,9 +1,10 @@
package eu.m724.vastapp.activity.dashboard
import androidx.compose.runtime.MutableState
import eu.m724.vastapp.vastai.data.Instance
import eu.m724.vastapp.vastai.data.User
data class DashboardUiState(
val isRefreshing: Boolean,
val user: User,
val error: String?
) { }
val refreshing: Int = 0
) {
}

View file

@ -3,30 +3,69 @@ package eu.m724.vastapp.activity.dashboard
import androidx.lifecycle.ViewModel
import eu.m724.vastapp.vastai.ApiRoute
import eu.m724.vastapp.vastai.VastApi
import eu.m724.vastapp.vastai.api.InstancesUrlRequestCallback
import eu.m724.vastapp.vastai.api.UserUrlRequestCallback
import eu.m724.vastapp.vastai.data.Instance
import eu.m724.vastapp.vastai.data.User
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class DashboardViewModel(initialUser: User, private val vastApi: VastApi) : ViewModel() { // TODO do something with the user
private val _uiState: MutableStateFlow<DashboardUiState> =
MutableStateFlow(DashboardUiState(false, initialUser, null))
MutableStateFlow(DashboardUiState(0))
val uiState: StateFlow<DashboardUiState> =
_uiState.asStateFlow()
private val _rentedInstances: MutableStateFlow<List<Instance>> = MutableStateFlow(emptyList())
val rentedInstances: StateFlow<List<Instance>> = _rentedInstances.asStateFlow()
private val _user: MutableStateFlow<User> = MutableStateFlow(initialUser)
val user: StateFlow<User> = _user.asStateFlow()
private val _refreshError: MutableStateFlow<List<String>> = MutableStateFlow(emptyList())
val refreshError: StateFlow<List<String>> = _refreshError.asStateFlow()
fun refresh() {
val request = vastApi.buildRequest(
_uiState.value = _uiState.value.copy(refreshing = 2)
_refreshError.value = emptyList()
val userRequest = vastApi.buildRequest(
ApiRoute.SHOW_USER,
UserUrlRequestCallback({ user ->
_uiState.value = _uiState.value.copy(isRefreshing = false, user = user)
UserUrlRequestCallback({ newUser ->
_user.value = newUser
_uiState.update {
it.copy(refreshing = it.refreshing - 1) // TODO I don't like how this looks
}
}, { apiFailure ->
_uiState.value = _uiState.value.copy(isRefreshing = false, error = apiFailure.errorMessage)
_refreshError.update { it + apiFailure.errorMessage!! }
_uiState.update {
it.copy(refreshing = it.refreshing - 1)
}
})
)
_uiState.value = _uiState.value.copy(isRefreshing = true)
request.start()
val instancesRequest = vastApi.buildRequest(
ApiRoute.GET_INSTANCES,
InstancesUrlRequestCallback({ instances ->
_rentedInstances.value = instances // TODO better way?
_uiState.update {
it.copy(refreshing = it.refreshing - 1)
}
}, { apiFailure ->
_refreshError.update { it + apiFailure.errorMessage!! }
_uiState.update {
it.copy(refreshing = it.refreshing - 1)
}
})
)
userRequest.start()
instancesRequest.start()
// TODO I don't like this function especially the last line
}
}

View file

@ -25,6 +25,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
@ -43,13 +44,15 @@ import eu.m724.vastapp.activity.dashboard.DashboardViewModel
fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
val uiState by dashboardViewModel.uiState.collectAsState()
val user by remember(uiState) { derivedStateOf { uiState.user } }
val user by dashboardViewModel.user.collectAsState()
val rentedInstances by dashboardViewModel.rentedInstances.collectAsState()
val remainingTime by rememberSaveable { mutableIntStateOf(6000000) }
val isRefreshing by remember(uiState) { derivedStateOf { uiState.refreshing > 0 } }
val scrollState = rememberScrollState()
PullToRefreshBox(
isRefreshing = uiState.isRefreshing,
isRefreshing = isRefreshing,
state = rememberPullToRefreshState(),
onRefresh = { dashboardViewModel.refresh() }
) {
@ -142,7 +145,7 @@ fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
modifier = Modifier.width(12.dp)
)
Text(
text = "4",
text = rentedInstances.size.toString(),
fontSize = 22.sp
)
}