Compare commits
No commits in common. "5f1787d6ff6e9609a4570f60267b4709eab5676a" and "127a31841ee1b1a4ed2d6fd5b5221cf2f3407f98" have entirely different histories.
5f1787d6ff
...
127a31841e
7 changed files with 36 additions and 145 deletions
|
@ -2,8 +2,6 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
|
|
@ -29,7 +29,6 @@ import androidx.navigation.compose.rememberNavController
|
|||
import eu.m724.vastapp.activity.dashboard.screen.Screen
|
||||
import eu.m724.vastapp.activity.dashboard.screen.BillingScreen
|
||||
import eu.m724.vastapp.activity.dashboard.screen.DashboardScreen
|
||||
import eu.m724.vastapp.activity.dashboard.screen.HelpScreen
|
||||
import eu.m724.vastapp.activity.dashboard.screen.InstancesScreen
|
||||
import eu.m724.vastapp.ui.theme.VastappTheme
|
||||
import eu.m724.vastapp.vastai.VastApi
|
||||
|
@ -55,8 +54,7 @@ class DashboardActivity : ComponentActivity() {
|
|||
val items = listOf(
|
||||
Screen.Dashboard,
|
||||
Screen.Instances,
|
||||
Screen.Billing,
|
||||
Screen.Help
|
||||
Screen.Billing
|
||||
)
|
||||
|
||||
val navController = rememberNavController()
|
||||
|
@ -72,7 +70,6 @@ class DashboardActivity : ComponentActivity() {
|
|||
composable("dashboard") { DashboardScreen(dashboardViewModel) }
|
||||
composable("instances") { InstancesScreen(dashboardViewModel) }
|
||||
composable("billing") { BillingScreen(dashboardViewModel) }
|
||||
composable("help") { HelpScreen(dashboardViewModel) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,37 @@
|
|||
package eu.m724.vastapp.activity.dashboard
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import eu.m724.vastapp.activity.login.LoginUiState
|
||||
import eu.m724.vastapp.vastai.ApiRoute
|
||||
import eu.m724.vastapp.vastai.VastApi
|
||||
import eu.m724.vastapp.vastai.api.UserUrlRequestCallback
|
||||
import eu.m724.vastapp.vastai.data.User
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class DashboardViewModel(initialUser: User, private val vastApi: VastApi) : ViewModel() { // TODO do something with the user
|
||||
class DashboardViewModel(private val _user: User, val vastApi: VastApi) : ViewModel() {
|
||||
private val _uiState: MutableStateFlow<DashboardUiState> =
|
||||
MutableStateFlow(DashboardUiState(false, initialUser, null))
|
||||
MutableStateFlow(DashboardUiState(false, _user, null))
|
||||
val uiState: StateFlow<DashboardUiState> =
|
||||
_uiState.asStateFlow()
|
||||
|
||||
private val _navigationEvent = MutableSharedFlow<String>()
|
||||
val navigationEvent: SharedFlow<String> = _navigationEvent.asSharedFlow()
|
||||
|
||||
fun navigateTo(route: String) {
|
||||
viewModelScope.launch {
|
||||
_navigationEvent.emit(route)
|
||||
}
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
val request = vastApi.buildRequest(
|
||||
ApiRoute.SHOW_USER,
|
||||
|
|
|
@ -1,70 +1,12 @@
|
|||
package eu.m724.vastapp.activity.dashboard.screen
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.m724.vastapp.R
|
||||
import eu.m724.vastapp.activity.dashboard.DashboardViewModel
|
||||
|
||||
class Billing {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BillingScreen(dashboardViewModel: DashboardViewModel) {
|
||||
val uiState by dashboardViewModel.uiState.collectAsState()
|
||||
|
||||
val user by remember(uiState) { derivedStateOf { uiState.user } }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Spacer(
|
||||
modifier = Modifier.height(30.dp)
|
||||
)
|
||||
|
||||
Card(
|
||||
modifier = Modifier.width(160.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp, 8.dp).height(IntrinsicSize.Min)
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.fillMaxHeight().aspectRatio(1f),
|
||||
painter = painterResource(id = R.drawable.baseline_monetization_on_24),
|
||||
contentDescription = "Balance"
|
||||
)
|
||||
Spacer(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "$%.2f".format(user.credit),
|
||||
fontSize = 24.sp,
|
||||
color = balanceColor(user.credit, user.balanceThreshold)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package eu.m724.vastapp.activity.dashboard.screen
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -17,14 +18,17 @@ import androidx.compose.material3.Icon
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.material3.pulltorefresh.pullToRefresh
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableDoubleStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
@ -33,8 +37,13 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import eu.m724.vastapp.R
|
||||
import eu.m724.vastapp.activity.dashboard.DashboardViewModel
|
||||
import eu.m724.vastapp.vastai.data.User
|
||||
import org.json.JSONObject
|
||||
|
||||
class Dashboard {
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class) // for pullRefresh
|
||||
@Composable
|
||||
fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
|
||||
|
@ -121,8 +130,6 @@ fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO maybe reuse that from Instances?
|
||||
|
||||
val instance = JSONObject()
|
||||
instance.put("id", 234523)
|
||||
instance.put("machine_id", 1121323)
|
||||
|
@ -133,6 +140,7 @@ fun DashboardScreen(dashboardViewModel: DashboardViewModel) {
|
|||
instance.put("gpu_ram", 24564)
|
||||
instance.put("vmem_usage", 0.339843)
|
||||
|
||||
|
||||
Column(
|
||||
modifier = Modifier.width(340.dp)
|
||||
) {
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package eu.m724.vastapp.activity.dashboard.screen
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.m724.vastapp.activity.dashboard.DashboardViewModel
|
||||
|
||||
@Composable
|
||||
fun HelpScreen(dashboardViewModel: DashboardViewModel) { // TODO make this a webview
|
||||
val context = LocalContext.current
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Button(onClick = {
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"))
|
||||
context.startActivity(browserIntent)
|
||||
}) {
|
||||
Text(text = "https://vast.ai/docs")
|
||||
}
|
||||
Text(text = "(this will be a webview)", fontSize = 12.sp)
|
||||
}
|
||||
}
|
|
@ -3,26 +3,16 @@ package eu.m724.vastapp.activity.dashboard.screen
|
|||
import android.widget.ProgressBar
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ContextualFlowRow
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
@ -34,35 +24,13 @@ import org.json.JSONObject
|
|||
class Instances {
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun InstancesScreen(dashboardViewModel: DashboardViewModel) {
|
||||
val uiState by dashboardViewModel.uiState.collectAsState()
|
||||
Column {
|
||||
|
||||
// TODO actually get instances
|
||||
|
||||
ContextualFlowRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
itemCount = 10,
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
val instance = JSONObject()
|
||||
instance.put("id", 234523)
|
||||
instance.put("machine_id", 1121323)
|
||||
instance.put("host_id", 5924)
|
||||
instance.put("gpu_name", "RTX 4090")
|
||||
instance.put("num_gpus", 2)
|
||||
instance.put("gpu_util", 70)
|
||||
instance.put("gpu_ram", 24564)
|
||||
instance.put("vmem_usage", 0.339843)
|
||||
|
||||
InstanceCard(instance = instance, modifier = Modifier.width(340.dp).padding(8.dp))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO maybe move this?
|
||||
@Composable
|
||||
fun InstanceCard(instance: JSONObject, modifier: Modifier = Modifier) {
|
||||
val gpuUsage = instance.getInt("gpu_util")
|
||||
|
@ -100,9 +68,7 @@ fun InstanceCard(instance: JSONObject, modifier: Modifier = Modifier) {
|
|||
modifier = Modifier.fillMaxWidth(0.5f)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
modifier = Modifier.fillMaxWidth().weight(1f)
|
||||
) {
|
||||
Text(text = "GPU: $gpuUsage%", fontSize = 12.sp)
|
||||
LinearProgressIndicator(
|
||||
|
@ -111,9 +77,7 @@ fun InstanceCard(instance: JSONObject, modifier: Modifier = Modifier) {
|
|||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
modifier = Modifier.fillMaxWidth().weight(1f)
|
||||
) {
|
||||
Text(text = "%.1f / %.1f G".format(vramGbUsed, vramGb), fontSize = 12.sp)
|
||||
LinearProgressIndicator(
|
||||
|
|
Loading…
Reference in a new issue