1package soy.iko.opencode.ui.file
3import androidx.compose.foundation.horizontalScroll
4import androidx.compose.foundation.layout.Box
5import androidx.compose.foundation.layout.fillMaxSize
6import androidx.compose.foundation.layout.padding
7import androidx.compose.foundation.rememberScrollState
8import androidx.compose.foundation.verticalScroll
9import androidx.compose.material.icons.Icons
10import androidx.compose.material.icons.automirrored.filled.ArrowBack
11import androidx.compose.material3.CircularProgressIndicator
12import androidx.compose.material3.ExperimentalMaterial3Api
13import androidx.compose.material3.Icon
14import androidx.compose.material3.IconButton
15import androidx.compose.material3.MaterialTheme
16import androidx.compose.material3.Scaffold
17import androidx.compose.material3.Text
18import androidx.compose.material3.TopAppBar
19import androidx.compose.runtime.Composable
20import androidx.compose.runtime.getValue
21import androidx.compose.ui.Alignment
22import androidx.compose.ui.Modifier
23import androidx.compose.ui.text.font.FontFamily
24import androidx.compose.ui.text.style.TextOverflow
25import androidx.compose.ui.unit.dp
26import androidx.lifecycle.compose.collectAsStateWithLifecycle
27import androidx.lifecycle.viewmodel.compose.viewModel
28import soy.iko.opencode.di.AppContainer
29import soy.iko.opencode.ui.vmFactory
31@OptIn(ExperimentalMaterial3Api::class)
34 container: AppContainer,
38 val vm: FileViewModel = viewModel(factory = vmFactory { FileViewModel(container, path) })
39 val state by vm.state.collectAsStateWithLifecycle()
44 title = { Text(path.substringAfterLast('/'), maxLines = 1, overflow = TextOverflow.Ellipsis) },
46 IconButton(onClick = onBack) {
47 Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
53 Box(modifier = Modifier.fillMaxSize().padding(padding)) {
55 state.loading -> CircularProgressIndicator(Modifier.align(Alignment.Center))
56 state.error != null -> Text(
58 modifier = Modifier.align(Alignment.Center).padding(24.dp),
59 color = MaterialTheme.colorScheme.error,
61 state.content?.isBinary == true -> Text(
62 "Binary file — preview not supported.",
63 modifier = Modifier.align(Alignment.Center).padding(24.dp),
64 color = MaterialTheme.colorScheme.onSurfaceVariant,
67 text = state.content?.content.orEmpty(),
70 .verticalScroll(rememberScrollState())
71 .horizontalScroll(rememberScrollState())
73 style = MaterialTheme.typography.bodySmall,
74 fontFamily = FontFamily.Monospace,
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list