* feat(#363): add descriptive text to loading spinners - Updates LoadingState composable to accept optional subtitle - Shows 'Fetching model providers...' on ModelScreen - Shows 'Loading channels...' on ChannelsScreen - Removes dead/unreachable CircularProgressIndicator from ModelScreen * fix(#363): pass loading_state_subtitle_models string to LoadingState --------- Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
96e754dd3b
commit
c0ebc8ec64
4 files changed
+30
-29
No files matched your search
@@ -73,7 +73,10 @@ fun ChannelsScreen(
|
||||
) { paddingValues ->
|
||||
when {
|
||||
state.isLoading && state.platforms.isEmpty() -> {
|
||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
||||
LoadingState(
|
||||
subtitle = stringResource(R.string.loading_state_subtitle_channels),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
|
||||
state.errorMessage != null -> {
|
||||
|
||||
@@ -35,7 +35,10 @@ import com.m57.hermescontrol.theme.LocalSpacing
|
||||
// ── Loading ───────────────────────────────────────────────────────────
|
||||
|
||||
@Composable
|
||||
fun LoadingState(modifier: Modifier = Modifier) {
|
||||
fun LoadingState(
|
||||
modifier: Modifier = Modifier,
|
||||
subtitle: String? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier =
|
||||
modifier
|
||||
@@ -43,6 +46,7 @@ fun LoadingState(modifier: Modifier = Modifier) {
|
||||
.testTag("loading_state"),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
CircularProgressIndicator(
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
strokeWidth = 3.dp,
|
||||
@@ -51,6 +55,15 @@ fun LoadingState(modifier: Modifier = Modifier) {
|
||||
.size(40.dp)
|
||||
.testTag("loading_spinner"),
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.m57.hermescontrol.ui.model
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -16,13 +15,10 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -83,7 +79,10 @@ fun ModelScreen(
|
||||
) { paddingValues ->
|
||||
when {
|
||||
state.isLoading && state.providers.isEmpty() -> {
|
||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
||||
LoadingState(
|
||||
subtitle = stringResource(R.string.loading_state_subtitle_models),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
|
||||
state.errorMessage != null -> {
|
||||
@@ -105,24 +104,6 @@ fun ModelScreen(
|
||||
}
|
||||
|
||||
else -> {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
if (state.isLoading && state.providers.isEmpty()) {
|
||||
CircularProgressIndicator()
|
||||
} else if (state.errorMessage != null && state.providers.isEmpty()) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(text = state.errorMessage ?: "", color = MaterialTheme.colorScheme.error)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
IconButton(onClick = { viewModel.loadModelOptions() }) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Refresh,
|
||||
contentDescription = stringResource(R.string.action_retry),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
@@ -258,8 +239,9 @@ fun ModelScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
.padding(12.dp),
|
||||
horizontalArrangement =
|
||||
Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
@@ -302,5 +284,3 @@ fun ModelScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,4 +397,9 @@
|
||||
<string name="landing_subtitle">Control panel for Hermes Agent</string>
|
||||
<string name="landing_action_auth_login">Auth Login</string>
|
||||
<string name="landing_action_pairing_login">Pairing Login</string>
|
||||
|
||||
<!-- Loading State -->
|
||||
<string name="loading_state_subtitle_default">Loading…</string>
|
||||
<string name="loading_state_subtitle_models">Fetching model providers…</string>
|
||||
<string name="loading_state_subtitle_channels">Loading channels…</string>
|
||||
</resources>
|
||||
Reference in new issue
Block a user