From f4b3760d8471e7ac5be9b92f8466eb137400baf4 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Wed, 31 Jul 2024 15:53:59 +0200 Subject: [PATCH] implement refreshing instances in viewmodel and accordingly in ui --- .../activity/dashboard/DashboardActivity.kt | 20 +++++++ .../activity/dashboard/DashboardUiState.kt | 9 ++-- .../activity/dashboard/DashboardViewModel.kt | 53 ++++++++++++++++--- .../activity/dashboard/screen/Dashboard.kt | 9 ++-- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardActivity.kt b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardActivity.kt index cabf005..0c36ae0 100644 --- a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardActivity.kt +++ b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardActivity.kt @@ -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 { diff --git a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardUiState.kt b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardUiState.kt index 6befee9..2ba0a12 100644 --- a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardUiState.kt +++ b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardUiState.kt @@ -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? -) { } \ No newline at end of file + val refreshing: Int = 0 +) { +} \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardViewModel.kt b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardViewModel.kt index 06feaa2..8d2dec7 100644 --- a/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/eu/m724/vastapp/activity/dashboard/DashboardViewModel.kt @@ -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 = - MutableStateFlow(DashboardUiState(false, initialUser, null)) + MutableStateFlow(DashboardUiState(0)) val uiState: StateFlow = _uiState.asStateFlow() + private val _rentedInstances: MutableStateFlow> = MutableStateFlow(emptyList()) + val rentedInstances: StateFlow> = _rentedInstances.asStateFlow() + + private val _user: MutableStateFlow = MutableStateFlow(initialUser) + val user: StateFlow = _user.asStateFlow() + + private val _refreshError: MutableStateFlow> = MutableStateFlow(emptyList()) + val refreshError: StateFlow> = _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 } + } \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/activity/dashboard/screen/Dashboard.kt b/app/src/main/java/eu/m724/vastapp/activity/dashboard/screen/Dashboard.kt index b497d56..77829fe 100644 --- a/app/src/main/java/eu/m724/vastapp/activity/dashboard/screen/Dashboard.kt +++ b/app/src/main/java/eu/m724/vastapp/activity/dashboard/screen/Dashboard.kt @@ -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 ) }