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 package eu.m724.vastapp.activity.dashboard
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
@ -14,11 +15,16 @@ import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp 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.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController 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.ui.theme.VastappTheme
import eu.m724.vastapp.vastai.VastApi import eu.m724.vastapp.vastai.VastApi
import eu.m724.vastapp.vastai.data.User import eu.m724.vastapp.vastai.data.User
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.chromium.net.CronetEngine import org.chromium.net.CronetEngine
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.coroutines.coroutineContext
class DashboardActivity : ComponentActivity() { class DashboardActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -49,6 +58,17 @@ class DashboardActivity : ComponentActivity() {
val dashboardViewModel = DashboardViewModel(user, vastApi) 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() enableEdgeToEdge()
setContent { setContent {
VastappTheme { VastappTheme {

View file

@ -1,9 +1,10 @@
package eu.m724.vastapp.activity.dashboard 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 import eu.m724.vastapp.vastai.data.User
data class DashboardUiState( data class DashboardUiState(
val isRefreshing: Boolean, val refreshing: Int = 0
val user: User, ) {
val error: String? }
) { }

View file

@ -3,30 +3,69 @@ package eu.m724.vastapp.activity.dashboard
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import eu.m724.vastapp.vastai.ApiRoute import eu.m724.vastapp.vastai.ApiRoute
import eu.m724.vastapp.vastai.VastApi 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.api.UserUrlRequestCallback
import eu.m724.vastapp.vastai.data.Instance
import eu.m724.vastapp.vastai.data.User import eu.m724.vastapp.vastai.data.User
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow 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 class DashboardViewModel(initialUser: User, private val vastApi: VastApi) : ViewModel() { // TODO do something with the user
private val _uiState: MutableStateFlow<DashboardUiState> = private val _uiState: MutableStateFlow<DashboardUiState> =
MutableStateFlow(DashboardUiState(false, initialUser, null)) MutableStateFlow(DashboardUiState(0))
val uiState: StateFlow<DashboardUiState> = val uiState: StateFlow<DashboardUiState> =
_uiState.asStateFlow() _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() { fun refresh() {
val request = vastApi.buildRequest( _uiState.value = _uiState.value.copy(refreshing = 2)
_refreshError.value = emptyList()
val userRequest = vastApi.buildRequest(
ApiRoute.SHOW_USER, ApiRoute.SHOW_USER,
UserUrlRequestCallback({ user -> UserUrlRequestCallback({ newUser ->
_uiState.value = _uiState.value.copy(isRefreshing = false, user = user) _user.value = newUser
_uiState.update {
it.copy(refreshing = it.refreshing - 1) // TODO I don't like how this looks
}
}, { apiFailure -> }, { 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) val instancesRequest = vastApi.buildRequest(
request.start() 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.collectAsState
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
@ -43,13 +44,15 @@ import eu.m724.vastapp.activity.dashboard.DashboardViewModel
fun DashboardScreen(dashboardViewModel: DashboardViewModel) { fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
val uiState by dashboardViewModel.uiState.collectAsState() 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 remainingTime by rememberSaveable { mutableIntStateOf(6000000) }
val isRefreshing by remember(uiState) { derivedStateOf { uiState.refreshing > 0 } }
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
PullToRefreshBox( PullToRefreshBox(
isRefreshing = uiState.isRefreshing, isRefreshing = isRefreshing,
state = rememberPullToRefreshState(), state = rememberPullToRefreshState(),
onRefresh = { dashboardViewModel.refresh() } onRefresh = { dashboardViewModel.refresh() }
) { ) {
@ -142,7 +145,7 @@ fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
modifier = Modifier.width(12.dp) modifier = Modifier.width(12.dp)
) )
Text( Text(
text = "4", text = rentedInstances.size.toString(),
fontSize = 22.sp fontSize = 22.sp
) )
} }