owenclave / app/src/main/java/io/nekohasekai/sagernet/ui/compose/screens/AboutScreen.kt

github - dev - back to tree - upstream
package io.nekohasekai.sagernet.ui.compose.screens import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.rememberTopAppBarState import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import io.nekohasekai.sagernet.BuildConfig import io.nekohasekai.sagernet.ui.compose.components.OwenclaveTopAppBar @OptIn(ExperimentalMaterial3Api::class) @Composable fun AboutScreen( onMenuClick: () -> Unit, ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState()) Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), containerColor = MaterialTheme.colorScheme.surfaceContainer, topBar = { OwenclaveTopAppBar( title = "About", navigationIcon = Icons.Filled.Menu, onNavigationClick = onMenuClick, scrollBehavior = scrollBehavior, ) }, ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() .padding(paddingValues) .verticalScroll(rememberScrollState()) .padding(24.dp) ) { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(), ) { io.nekohasekai.sagernet.ui.compose.components.AppLogo( style = io.nekohasekai.sagernet.ui.compose.components.AppLogoStyle.fromId( io.nekohasekai.sagernet.database.DataStore.appLogo ), size = 108.dp, ) Spacer(Modifier.height(16.dp)) Text( text = "Owenclave", style = MaterialTheme.typography.headlineMedium, ) Spacer(Modifier.height(4.dp)) Text( text = "Version ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) Spacer(Modifier.height(32.dp)) AboutSection(title = "Project", items = listOf( "GitHub" to "https://github.com/owenewans/owenclave", "License" to "GPL-3.0", "Based on" to "SagerNet/exclave", )) Spacer(Modifier.height(16.dp)) AboutSection(title = "Components", items = listOf( "Core" to "libowenclavecore", "Protocols" to "SOCKS, HTTP, SS, SSR, VMess, VLESS, Trojan, Naive, Hysteria2, SSH, WireGuard, Mieru, TUIC, Juicity, HTTP/3, AnyTLS, ShadowQUIC, TrustTunnel, Snell, OLCRTC", )) Spacer(Modifier.height(16.dp)) AboutSection(title = "Credits", items = listOf( "SagerNet" to "nekohasekai", "Shadowsocks" to "Mygod Studio", "V2Ray" to "v2ray project", )) } } } } @Composable private fun AboutSection( title: String, items: List>, ) { Card( modifier = Modifier.fillMaxWidth(), shape = MaterialTheme.shapes.large, ) { Column(modifier = Modifier.padding(20.dp)) { Text( text = title, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.primary, ) Spacer(Modifier.height(12.dp)) items.forEach { (key, value) -> Row( modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = key, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, ) Text( text = value, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface, ) } } } } }