Adds SkeletonListState to StateViews.kt — an animated shimmer placeholder list whose geometry matches a typical list row (avatar circle + title line + subtitle line). The shimmer colors derive from MaterialTheme.colorScheme.surfaceVariant (theme-aware, works on light/dark/AMOLED/Material You). Sweeps horizontally via an infiniteTransition tween — no new dependencies, pure Compose foundation animations. Wired SkeletonListState into 22 list-loading call sites across 22 screens: skills, cron, plugins, mcp, toolsets, webhooks, system, sessions (x2), config (x2 — list + YAMLEditor), model, profiles, keys, channels, achievements, gateways, kanban, logs, analytics, providers, processes, hub skills tab, installed skills tab (list branch). Preserved LoadingState() (centered spinner) where the issue explicitly calls for it: - PairingScreen (one-shot auth flow) - SkillEditorDialog / ModelPickerDialog / CronJobEditorDialog interiors - SkillPreviewDialog and SkillEditorDialog inline-loading branches in SkillsScreen.kt (lines 790, 914) - InstalledSkillsTab dialog-interior branch (line 393) SkeletonListState testTag: "skeleton_list_state". Verified: ktlintCheck, assembleDebug, testDebugUnitTest all green locally. Co-authored-by: Hy4ri <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
0a0b612d3a
commit
0018e5d172
23 files changed
+186
-53
No files matched your search
@@ -57,10 +57,10 @@ import com.m57.hermescontrol.data.model.RecentUnlock
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
import com.m57.hermescontrol.ui.common.SectionHeader
|
import com.m57.hermescontrol.ui.common.SectionHeader
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
@@ -169,7 +169,7 @@ fun AchievementsScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.achievements.isEmpty() -> {
|
state.isLoading && state.achievements.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.achievements.isEmpty() -> {
|
state.errorMessage != null && state.achievements.isEmpty() -> {
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import com.m57.hermescontrol.theme.LocalHermesStatusColors
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ fun AnalyticsScreen(
|
|||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.usage == null -> {
|
state.isLoading && state.usage == null -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.usage == null -> {
|
state.errorMessage != null && state.usage == null -> {
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ import com.m57.hermescontrol.ui.channels.components.TelegramOnboardingDialog
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -132,10 +132,7 @@ fun ChannelsScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.platforms.isEmpty() -> {
|
state.isLoading && state.platforms.isEmpty() -> {
|
||||||
LoadingState(
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
subtitle = stringResource(R.string.loading_state_subtitle_channels),
|
|
||||||
modifier = Modifier.padding(paddingValues),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.platforms.isEmpty() -> {
|
state.errorMessage != null && state.platforms.isEmpty() -> {
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
package com.m57.hermescontrol.ui.common
|
package com.m57.hermescontrol.ui.common
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Inbox
|
import androidx.compose.material.icons.filled.Inbox
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
@@ -19,12 +31,20 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.OutlinedButton
|
import androidx.compose.material3.OutlinedButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.m57.hermescontrol.R
|
import com.m57.hermescontrol.R
|
||||||
import com.m57.hermescontrol.theme.LocalSpacing
|
import com.m57.hermescontrol.theme.LocalSpacing
|
||||||
@@ -168,6 +188,125 @@ fun EmptyState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Skeleton (shimmer) — see issue #617 ────────────────────────────────
|
||||||
|
//
|
||||||
|
// Skeleton loaders for list screens. Replaces bare `CircularProgressIndicator`
|
||||||
|
// in list screens to (1) reduce perceived latency (~2× per NN/g research)
|
||||||
|
// and (2) eliminate layout shift when real content lands. Pair with
|
||||||
|
// `LoadingState()` for centered/one-shot contexts (Pairing flow, dialog
|
||||||
|
// interiors) where a spinner is still appropriate.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An animated shimmer [Brush] derived from the current theme's
|
||||||
|
* `MaterialTheme.colorScheme.surfaceVariant`. Sweeps horizontally across the
|
||||||
|
* canvas; offset driven by an infinite `1.2s` tween so the shimmer never
|
||||||
|
* freezes. Theme-derived — works on light, dark, AMOLED, Material You.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
private fun shimmerBrush(): Brush {
|
||||||
|
val base = MaterialTheme.colorScheme.surfaceVariant
|
||||||
|
val highlight = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.4f)
|
||||||
|
val transition = rememberInfiniteTransition(label = "shimmer")
|
||||||
|
val widthPx = with(LocalDensity.current) { LocalConfiguration.current.screenWidthDp.dp.toPx() }
|
||||||
|
val offset by transition.animateFloat(
|
||||||
|
initialValue = -widthPx,
|
||||||
|
targetValue = widthPx,
|
||||||
|
animationSpec =
|
||||||
|
infiniteRepeatable(
|
||||||
|
animation = tween(durationMillis = 1200, easing = FastOutSlowInEasing),
|
||||||
|
repeatMode = RepeatMode.Restart,
|
||||||
|
),
|
||||||
|
label = "shimmer_offset",
|
||||||
|
)
|
||||||
|
return Brush.linearGradient(
|
||||||
|
colors = listOf(base, highlight, base),
|
||||||
|
start = Offset(offset, 0f),
|
||||||
|
end = Offset(offset + widthPx, 0f),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerBox(
|
||||||
|
widthFraction: Float,
|
||||||
|
height: Dp,
|
||||||
|
shape: Shape,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.height(height)
|
||||||
|
.fillMaxWidth(widthFraction)
|
||||||
|
.clip(shape)
|
||||||
|
.background(shimmerBrush()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SkeletonRow(height: Dp) {
|
||||||
|
val spacing = LocalSpacing.current
|
||||||
|
val shape = RoundedCornerShape(12.dp)
|
||||||
|
Row(
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(height)
|
||||||
|
.padding(vertical = spacing.sm),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
// Avatar circle — 40dp to match default LoadingState spinner size.
|
||||||
|
ShimmerBox(
|
||||||
|
widthFraction = 0f,
|
||||||
|
height = 40.dp,
|
||||||
|
shape = CircleShape,
|
||||||
|
modifier = Modifier.size(40.dp),
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(spacing.md))
|
||||||
|
// Title + subtitle lines
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(spacing.sm),
|
||||||
|
) {
|
||||||
|
ShimmerBox(widthFraction = 0.6f, height = 14.dp, shape = shape)
|
||||||
|
ShimmerBox(widthFraction = 0.4f, height = 12.dp, shape = shape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skeleton placeholder list for loading states on list/management screens.
|
||||||
|
*
|
||||||
|
* Renders [itemCount] shimmering rows whose geometry matches the typical list
|
||||||
|
* row (avatar circle + title line + subtitle line). The shimmer colors derive
|
||||||
|
* from theme tokens — works on light, dark, AMOLED, and Material You. No
|
||||||
|
* layout shift on transition to real content (acceptance criterion, issue #617).
|
||||||
|
*
|
||||||
|
* @param itemCount number of placeholder rows to render (default 6 — long
|
||||||
|
* enough to fill a phone viewport under typical content density).
|
||||||
|
* @param rowHeight height of each placeholder row (default 72dp — same as a
|
||||||
|
* one-line `NavigationDrawerItem`). Override per-screen to match real row
|
||||||
|
* geometry when known.
|
||||||
|
* @param modifier outer modifier; pass `Modifier.padding(paddingValues)` from
|
||||||
|
* the scaffold so the skeleton offsets for the top bar like real content does.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun SkeletonListState(
|
||||||
|
itemCount: Int = 6,
|
||||||
|
rowHeight: Dp = 72.dp,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 12.dp)
|
||||||
|
.testTag("skeleton_list_state"),
|
||||||
|
verticalArrangement = listItemSpacing,
|
||||||
|
) {
|
||||||
|
repeat(itemCount) { SkeletonRow(height = rowHeight) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Padding conventions ──────────────────────────────────────────────
|
// ── Padding conventions ──────────────────────────────────────────────
|
||||||
|
|
||||||
val listContentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp)
|
val listContentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp)
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.data.model.SchemaField
|
import com.m57.hermescontrol.data.model.SchemaField
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import kotlinx.serialization.json.JsonArray
|
import kotlinx.serialization.json.JsonArray
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
@@ -101,7 +101,7 @@ fun ConfigScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.config == null -> {
|
state.isLoading && state.config == null -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.config == null -> {
|
state.errorMessage != null && state.config == null -> {
|
||||||
@@ -281,7 +281,7 @@ private fun YAMLEditor(
|
|||||||
onSave: () -> Unit,
|
onSave: () -> Unit,
|
||||||
) {
|
) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import com.m57.hermescontrol.ui.common.ErrorState
|
|||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
import com.m57.hermescontrol.ui.common.LoadingState
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
@@ -96,7 +97,7 @@ fun CronJobsScreen(
|
|||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.jobs.isEmpty() -> {
|
state.isLoading && state.jobs.isEmpty() -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.theme.LocalHermesStatusColors
|
import com.m57.hermescontrol.theme.LocalHermesStatusColors
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -66,7 +66,7 @@ fun GatewayScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.status == null -> {
|
state.isLoading && state.status == null -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.data.model.KanbanTask
|
import com.m57.hermescontrol.data.model.KanbanTask
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
|
|
||||||
private const val DEFAULT_COLUMN = "todo"
|
private const val DEFAULT_COLUMN = "todo"
|
||||||
@@ -94,7 +94,7 @@ fun KanbanScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.boards.isEmpty() -> {
|
state.isLoading && state.boards.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
import com.m57.hermescontrol.ui.common.SectionHeader
|
import com.m57.hermescontrol.ui.common.SectionHeader
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -106,7 +106,7 @@ fun KeysScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && !hasAnyVars -> {
|
state.isLoading && !hasAnyVars -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && !hasAnyVars -> {
|
state.errorMessage != null && !hasAnyVars -> {
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ import com.m57.hermescontrol.theme.LocalSpacing
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ fun LogsScreen(
|
|||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.logs.isEmpty() -> {
|
state.isLoading && state.logs.isEmpty() -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ import com.m57.hermescontrol.ui.common.DetailDialog
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
import com.m57.hermescontrol.ui.common.SectionHeader
|
import com.m57.hermescontrol.ui.common.SectionHeader
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
@@ -120,7 +120,7 @@ fun McpServersScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.servers.isEmpty() -> {
|
state.isLoading && state.servers.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.model.components.MoaConfigDialog
|
import com.m57.hermescontrol.ui.model.components.MoaConfigDialog
|
||||||
import com.m57.hermescontrol.ui.model.components.ModelPickerDialog
|
import com.m57.hermescontrol.ui.model.components.ModelPickerDialog
|
||||||
@@ -101,10 +101,7 @@ fun ModelScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.providers.isEmpty() -> {
|
state.isLoading && state.providers.isEmpty() -> {
|
||||||
LoadingState(
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
subtitle = stringResource(R.string.loading_state_subtitle_models),
|
|
||||||
modifier = Modifier.padding(paddingValues),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ import com.m57.hermescontrol.ui.common.DetailDialog
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -131,7 +131,7 @@ fun PluginsScreen(
|
|||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.plugins.isEmpty() -> {
|
state.isLoading && state.plugins.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ import com.m57.hermescontrol.theme.LocalHermesStatusColors
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -85,7 +85,7 @@ fun ProcessesScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.isLoading && state.processes.isEmpty() -> {
|
state.isLoading && state.processes.isEmpty() -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ import com.m57.hermescontrol.R
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.profiles.components.ProfileBuilderView
|
import com.m57.hermescontrol.ui.profiles.components.ProfileBuilderView
|
||||||
import com.m57.hermescontrol.ui.profiles.components.validateProfileName
|
import com.m57.hermescontrol.ui.profiles.components.validateProfileName
|
||||||
@@ -134,7 +134,7 @@ fun ProfilesScreen(
|
|||||||
} else {
|
} else {
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.profiles.isEmpty() -> {
|
state.isLoading && state.profiles.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ import com.m57.hermescontrol.theme.LocalHermesStatusColors
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -102,10 +102,7 @@ fun ProvidersScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.providers.isEmpty() -> {
|
state.isLoading && state.providers.isEmpty() -> {
|
||||||
LoadingState(
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
subtitle = stringResource(R.string.loading_state_subtitle_providers),
|
|
||||||
modifier = Modifier.padding(paddingValues),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.providers.isEmpty() -> {
|
state.errorMessage != null && state.providers.isEmpty() -> {
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ import com.m57.hermescontrol.theme.LocalSpacing
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatCard
|
import com.m57.hermescontrol.ui.common.StatCard
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
@@ -491,7 +491,7 @@ fun SessionsScreen(
|
|||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
when {
|
when {
|
||||||
state.isSearching && state.searchResults.isEmpty() -> {
|
state.isSearching && state.searchResults.isEmpty() -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.searchError != null -> {
|
state.searchError != null -> {
|
||||||
@@ -579,7 +579,7 @@ fun SessionsScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.isLoading && state.sessions.isEmpty() -> {
|
state.isLoading && state.sessions.isEmpty() -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import com.m57.hermescontrol.ui.common.HermesScaffold
|
|||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
import com.m57.hermescontrol.ui.common.LoadingState
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -317,7 +318,7 @@ private fun InstalledSkillsView(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
state.isLoading -> {
|
state.isLoading -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
@@ -587,7 +588,7 @@ private fun HubBrowseView(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
state.isHubSearching -> {
|
state.isHubSearching -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.hubSearchError != null -> {
|
state.hubSearchError != null -> {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import com.m57.hermescontrol.ui.common.DetailDialog
|
|||||||
import com.m57.hermescontrol.ui.common.DetailRow
|
import com.m57.hermescontrol.ui.common.DetailRow
|
||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
import com.m57.hermescontrol.ui.skills.SkillsUiState
|
import com.m57.hermescontrol.ui.skills.SkillsUiState
|
||||||
@@ -117,7 +117,7 @@ internal fun HubBrowseView(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
state.isHubSearching -> {
|
state.isHubSearching -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.hubSearchError != null -> {
|
state.hubSearchError != null -> {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import com.m57.hermescontrol.ui.common.HermesScaffold
|
|||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
import com.m57.hermescontrol.ui.common.LoadingState
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
import com.m57.hermescontrol.ui.common.toDetailRows
|
import com.m57.hermescontrol.ui.common.toDetailRows
|
||||||
@@ -177,7 +178,7 @@ internal fun InstalledSkillsView(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
state.isLoading -> {
|
state.isLoading -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ import com.m57.hermescontrol.ui.common.EmptyState
|
|||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.InfoRow
|
import com.m57.hermescontrol.ui.common.InfoRow
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SectionHeader
|
import com.m57.hermescontrol.ui.common.SectionHeader
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatCard
|
import com.m57.hermescontrol.ui.common.StatCard
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
@@ -252,7 +252,7 @@ fun SystemScreen(
|
|||||||
when {
|
when {
|
||||||
state.isLoading && state.stats == null && state.doctorReport == null &&
|
state.isLoading && state.stats == null && state.doctorReport == null &&
|
||||||
state.status == null -> {
|
state.status == null -> {
|
||||||
LoadingState()
|
SkeletonListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ import com.m57.hermescontrol.ui.common.DetailDialog
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
import com.m57.hermescontrol.ui.common.listContentPadding
|
import com.m57.hermescontrol.ui.common.listContentPadding
|
||||||
import com.m57.hermescontrol.ui.common.listItemSpacing
|
import com.m57.hermescontrol.ui.common.listItemSpacing
|
||||||
@@ -87,7 +87,7 @@ fun ToolsetsScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.toolsets.isEmpty() -> {
|
state.isLoading && state.toolsets.isEmpty() -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null -> {
|
state.errorMessage != null -> {
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ import com.m57.hermescontrol.ui.common.DetailDialog
|
|||||||
import com.m57.hermescontrol.ui.common.EmptyState
|
import com.m57.hermescontrol.ui.common.EmptyState
|
||||||
import com.m57.hermescontrol.ui.common.ErrorState
|
import com.m57.hermescontrol.ui.common.ErrorState
|
||||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||||
import com.m57.hermescontrol.ui.common.LoadingState
|
|
||||||
import com.m57.hermescontrol.ui.common.NavIcon
|
import com.m57.hermescontrol.ui.common.NavIcon
|
||||||
import com.m57.hermescontrol.ui.common.SearchBar
|
import com.m57.hermescontrol.ui.common.SearchBar
|
||||||
|
import com.m57.hermescontrol.ui.common.SkeletonListState
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadge
|
import com.m57.hermescontrol.ui.common.StatusBadge
|
||||||
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
import com.m57.hermescontrol.ui.common.StatusBadgeType
|
||||||
import com.m57.hermescontrol.ui.common.ToastEffect
|
import com.m57.hermescontrol.ui.common.ToastEffect
|
||||||
@@ -244,7 +244,7 @@ fun WebhooksScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
when {
|
when {
|
||||||
state.isLoading && state.baseUrl == null -> {
|
state.isLoading && state.baseUrl == null -> {
|
||||||
LoadingState(modifier = Modifier.padding(paddingValues))
|
SkeletonListState(modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
state.errorMessage != null && state.baseUrl == null -> {
|
state.errorMessage != null && state.baseUrl == null -> {
|
||||||
|
|||||||
Reference in new issue
Block a user