mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
243 lines
8.0 KiB
Kotlin
243 lines
8.0 KiB
Kotlin
package com.bintianqi.owndroid.ui
|
|
|
|
import android.widget.Toast
|
|
import androidx.annotation.DrawableRes
|
|
import androidx.annotation.StringRes
|
|
import androidx.compose.animation.animateContentSize
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
|
import androidx.compose.material3.MaterialTheme.typography
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.clip
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.platform.LocalContext
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.navigation.NavBackStackEntry
|
|
import androidx.navigation.NavHostController
|
|
import com.bintianqi.owndroid.R
|
|
import com.bintianqi.owndroid.writeClipBoard
|
|
import com.bintianqi.owndroid.zhCN
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
|
|
@Composable
|
|
fun SubPageItem(
|
|
@StringRes title: Int,
|
|
desc:String,
|
|
@DrawableRes icon: Int? = null,
|
|
operation: () -> Unit
|
|
) {
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth().clickable(onClick = operation).padding(top = 15.dp, bottom = 15.dp, start = 30.dp, end = 12.dp),
|
|
verticalAlignment = Alignment.CenterVertically
|
|
) {
|
|
if(icon != null) {
|
|
Icon(painter = painterResource(icon), contentDescription = stringResource(title), modifier = Modifier.padding(top = 1.dp))
|
|
Spacer(Modifier.padding(start = 15.dp))
|
|
}
|
|
Column {
|
|
Text(text = stringResource(title), style = typography.titleLarge, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp))
|
|
if(desc!="") { Text(text = desc, color = colorScheme.onBackground.copy(alpha = 0.8F)) }
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun NavIcon(operation: () -> Unit) {
|
|
Icon(
|
|
painter = painterResource(R.drawable.arrow_back_fill0),
|
|
contentDescription = "Back arrow",
|
|
modifier = Modifier
|
|
.padding(horizontal = 6.dp)
|
|
.clip(RoundedCornerShape(50))
|
|
.clickable(onClick = operation)
|
|
.padding(5.dp)
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun Information(content: @Composable ()->Unit) {
|
|
Column(modifier = Modifier.fillMaxWidth().padding(start = 5.dp, top = 20.dp)) {
|
|
Icon(
|
|
painter = painterResource(R.drawable.info_fill0),
|
|
contentDescription = "info",
|
|
tint = colorScheme.onBackground.copy(alpha = 0.8F)
|
|
)
|
|
Spacer(Modifier.padding(vertical = 1.dp))
|
|
Column(modifier = Modifier.padding(start = 2.dp)) {
|
|
content()
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun RadioButtonItem(
|
|
@StringRes text: Int,
|
|
selected: Boolean,
|
|
operation: () -> Unit,
|
|
textColor: Color = colorScheme.onBackground
|
|
) {
|
|
RadioButtonItem(stringResource(text), selected, operation, textColor)
|
|
}
|
|
|
|
@Composable
|
|
fun RadioButtonItem(
|
|
text: String,
|
|
selected: Boolean,
|
|
operation: () -> Unit,
|
|
textColor: Color = colorScheme.onBackground
|
|
) {
|
|
Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier
|
|
.fillMaxWidth()
|
|
.clip(RoundedCornerShape(25))
|
|
.clickable(onClick = operation)
|
|
) {
|
|
RadioButton(selected = selected, onClick = operation)
|
|
Text(text = text, color = textColor, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp))
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun CheckBoxItem(
|
|
@StringRes text: Int,
|
|
checked: Boolean,
|
|
operation: (Boolean) -> Unit,
|
|
textColor: Color = colorScheme.onBackground
|
|
) {
|
|
Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier
|
|
.fillMaxWidth()
|
|
.clip(RoundedCornerShape(25))
|
|
.clickable { operation(!checked) }
|
|
) {
|
|
Checkbox(
|
|
checked = checked,
|
|
onCheckedChange = operation
|
|
)
|
|
Text(text = stringResource(text), color = textColor, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp))
|
|
}
|
|
}
|
|
|
|
|
|
@Composable
|
|
fun SwitchItem(
|
|
@StringRes title: Int,
|
|
desc: String,
|
|
@DrawableRes icon: Int?,
|
|
getState: ()->Boolean,
|
|
onCheckedChange: (Boolean)->Unit,
|
|
enable: Boolean = true,
|
|
onClickBlank: (() -> Unit)? = null,
|
|
padding: Boolean = true
|
|
) {
|
|
var state by remember { mutableStateOf(getState()) }
|
|
SwitchItem(title, desc, icon, state, { onCheckedChange(it); state = getState() }, enable, onClickBlank, padding)
|
|
}
|
|
|
|
@Composable
|
|
fun SwitchItem(
|
|
@StringRes title: Int,
|
|
desc: String,
|
|
@DrawableRes icon: Int?,
|
|
state: Boolean,
|
|
onCheckedChange: (Boolean)->Unit,
|
|
enable: Boolean = true,
|
|
onClickBlank: (() -> Unit)? = null,
|
|
padding: Boolean = true
|
|
) {
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.clickable(enabled = onClickBlank != null, onClick = onClickBlank?:{})
|
|
.padding(top = 5.dp, bottom = 5.dp, start = if(padding) 30.dp else 0.dp, end = if(padding) 12.dp else 0.dp)
|
|
) {
|
|
Row(
|
|
verticalAlignment = Alignment.CenterVertically,
|
|
modifier = Modifier.align(Alignment.CenterStart)
|
|
) {
|
|
if(icon != null) {
|
|
Icon(painter = painterResource(icon),contentDescription = null)
|
|
Spacer(Modifier.padding(start = 15.dp))
|
|
}
|
|
Column(modifier = Modifier.padding(end = 60.dp)) {
|
|
Text(text = stringResource(title), style = typography.titleLarge)
|
|
if(desc!="") {
|
|
Text(text = desc, color = colorScheme.onBackground.copy(alpha = 0.8F))
|
|
}
|
|
if(zhCN) { Spacer(Modifier.padding(vertical = 1.dp)) }
|
|
}
|
|
}
|
|
Switch(
|
|
checked = state, onCheckedChange = { onCheckedChange(it) },
|
|
modifier = Modifier.align(Alignment.CenterEnd), enabled = enable
|
|
)
|
|
}
|
|
}
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
@Composable
|
|
fun TopBar(
|
|
backStackEntry: NavBackStackEntry?,
|
|
navCtrl: NavHostController,
|
|
localNavCtrl: NavHostController,
|
|
title: @Composable ()->Unit = {}
|
|
) {
|
|
TopAppBar(
|
|
title = title,
|
|
navigationIcon = {
|
|
NavIcon{
|
|
if(backStackEntry?.destination?.route == "Home") { navCtrl.navigateUp() } else { localNavCtrl.navigateUp() }
|
|
}
|
|
},
|
|
colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background)
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
fun CopyTextButton(@StringRes label: Int, content: String) {
|
|
val context = LocalContext.current
|
|
var ok by remember{ mutableStateOf(false) }
|
|
val scope = rememberCoroutineScope()
|
|
Button(
|
|
onClick = {
|
|
if(!ok) {
|
|
scope.launch {
|
|
if(writeClipBoard(context,content)) { ok = true; delay(2000); ok = false }
|
|
else{ Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show() }
|
|
}
|
|
}
|
|
}
|
|
) {
|
|
Row(
|
|
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.animateContentSize()
|
|
) {
|
|
Icon(painter = painterResource(if(ok) R.drawable.check_fill0 else R.drawable.content_copy_fill0), contentDescription = null)
|
|
Spacer(modifier = Modifier.padding(horizontal = 2.dp))
|
|
Text(text = stringResource(if(ok) R.string.success else label))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun CardItem(@StringRes title: Int, @StringRes text: Int) {
|
|
CardItem(title, stringResource(text))
|
|
}
|
|
|
|
@Composable
|
|
fun CardItem(@StringRes title: Int, text: String) {
|
|
Card(modifier = Modifier.fillMaxWidth().padding(vertical = 6.dp)) {
|
|
Text(text = stringResource(title), style = typography.titleLarge, modifier = Modifier.padding(start = 8.dp, top = 6.dp))
|
|
SelectionContainer {
|
|
Text(text = text, modifier = Modifier.padding(start = 8.dp, bottom = 6.dp))
|
|
}
|
|
}
|
|
}
|