package soy.iko.opencode.ui.components import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack 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.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import soy.iko.opencode.R /** * The app's standard top bar: a title (with optional subtitle), an optional up/back button, an * optional inline loading indicator, and trailing actions. Extracted so the many plain * back-title-actions screens share one implementation instead of hand-rolling a [TopAppBar] each. * Screens with a bespoke title (dropdown server switcher, clickable model picker) keep their own bar. */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun AppTopBar( title: String, onBack: (() -> Unit)? = null, scrollBehavior: TopAppBarScrollBehavior? = null, subtitle: String? = null, loading: Boolean = false, actions: @Composable RowScope.() -> Unit = {}, ) { TopAppBar( title = { if (subtitle != null) { Column { Text(title, maxLines = 1, overflow = TextOverflow.Ellipsis) Text( subtitle, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } else { Text(title, maxLines = 1, overflow = TextOverflow.Ellipsis) } }, navigationIcon = { if (onBack != null) { IconButton(onClick = onBack) { Icon( Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back), ) } } }, actions = { if (loading) { Box(modifier = Modifier.size(40.dp), contentAlignment = Alignment.Center) { CircularProgressIndicator( Modifier.size(20.dp), strokeWidth = 2.dp, color = MaterialTheme.colorScheme.onSurfaceVariant, ) } } actions() }, scrollBehavior = scrollBehavior, colors = TopAppBarDefaults.topAppBarColors(), ) }