package soy.iko.opencode.ui.file import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll 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.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import soy.iko.opencode.di.AppContainer import soy.iko.opencode.ui.vmFactory @OptIn(ExperimentalMaterial3Api::class) @Composable fun FileViewScreen( container: AppContainer, path: String, onBack: () -> Unit, ) { val vm: FileViewModel = viewModel(factory = vmFactory { FileViewModel(container, path) }) val state by vm.state.collectAsStateWithLifecycle() Scaffold( topBar = { TopAppBar( title = { Text(path.substringAfterLast('/'), maxLines = 1, overflow = TextOverflow.Ellipsis) }, navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } }, ) }, ) { padding -> Box(modifier = Modifier.fillMaxSize().padding(padding)) { when { state.loading -> CircularProgressIndicator(Modifier.align(Alignment.Center)) state.error != null -> Text( state.error!!, modifier = Modifier.align(Alignment.Center).padding(24.dp), color = MaterialTheme.colorScheme.error, ) state.content?.isBinary == true -> Text( "Binary file — preview not supported.", modifier = Modifier.align(Alignment.Center).padding(24.dp), color = MaterialTheme.colorScheme.onSurfaceVariant, ) else -> Text( text = state.content?.content.orEmpty(), modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .horizontalScroll(rememberScrollState()) .padding(12.dp), style = MaterialTheme.typography.bodySmall, fontFamily = FontFamily.Monospace, ) } } } }