You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
13 KiB
377 lines
13 KiB
package com.gyf.csams
|
|
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.setContent
|
|
import androidx.compose.animation.animateColor
|
|
import androidx.compose.animation.core.*
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.text.KeyboardActions
|
|
import androidx.compose.foundation.text.KeyboardOptions
|
|
import androidx.compose.material.*
|
|
import androidx.compose.runtime.*
|
|
import androidx.compose.runtime.livedata.observeAsState
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.platform.LocalFocusManager
|
|
import androidx.compose.ui.text.buildAnnotatedString
|
|
import androidx.compose.ui.text.input.ImeAction
|
|
import androidx.compose.ui.text.input.KeyboardType
|
|
import androidx.compose.ui.text.withStyle
|
|
import androidx.compose.ui.tooling.preview.Preview
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
import com.gyf.csams.account.model.DialogMessage
|
|
import com.gyf.csams.account.model.RegisterViewModel
|
|
import com.gyf.csams.ui.theme.CSAMSTheme
|
|
|
|
class MainActivity : ComponentActivity() {
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
setContent {
|
|
|
|
CSAMSTheme {
|
|
// A surface container using the 'background' color from the theme
|
|
Surface(color = MaterialTheme.colors.background) {
|
|
Register()
|
|
RegisterDialog()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 注册表单
|
|
*
|
|
*/
|
|
@Composable
|
|
fun Register(registerViewModel: RegisterViewModel=viewModel()){
|
|
val scaffoldState = rememberScaffoldState()
|
|
Scaffold(scaffoldState=scaffoldState) {
|
|
Row(
|
|
horizontalArrangement = Arrangement.Center,
|
|
verticalAlignment = Alignment.CenterVertically,
|
|
modifier = Modifier.fillMaxSize()
|
|
) {
|
|
Column(modifier = Modifier.width(IntrinsicSize.Min)) {
|
|
val name: String by registerViewModel.name.observeAsState("")
|
|
Text(buildAnnotatedString {
|
|
withStyle(
|
|
style = MaterialTheme.typography.subtitle1.toSpanStyle()
|
|
.copy(color = MaterialTheme.colors.primary)
|
|
) {
|
|
append(name)
|
|
}
|
|
withStyle(style = MaterialTheme.typography.subtitle1.toSpanStyle()) {
|
|
append(registerViewModel.welcomeStart)
|
|
}
|
|
withStyle(style = MaterialTheme.typography.subtitle2.toSpanStyle()) {
|
|
append(registerViewModel.welcomeEnd)
|
|
}
|
|
withStyle(
|
|
style = MaterialTheme.typography.subtitle2.toSpanStyle()
|
|
.copy(color = MaterialTheme.colors.secondary)
|
|
) {
|
|
append(BuildConfig.APP_NAME)
|
|
}
|
|
})
|
|
|
|
StudentId()
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
Name(name)
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
|
|
val isValidForm: Boolean by registerViewModel.isValidForm.observeAsState(false)
|
|
if(isValidForm) {
|
|
Password()
|
|
}
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
RegisterButton(isValidForm,scaffoldState = scaffoldState)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 学号
|
|
*
|
|
* @param registerViewModel
|
|
*/
|
|
@Composable
|
|
fun StudentId(registerViewModel: RegisterViewModel=viewModel()){
|
|
Column {
|
|
|
|
val studentId: String by registerViewModel.studentId.observeAsState("")
|
|
val isValidStudentId : Boolean by registerViewModel.isValidStudentId.observeAsState(false)
|
|
val focusManager = LocalFocusManager.current
|
|
OutlinedTextField(
|
|
value = studentId,
|
|
onValueChange = { registerViewModel.onStudentIdChange(it) },
|
|
label = { Text(text = registerViewModel.studentIdDesc) },
|
|
placeholder = { Text(text = registerViewModel.studentIdPlaceholder) },
|
|
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
|
keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Number,imeAction = ImeAction.Done),
|
|
singleLine = true,
|
|
isError = !isValidStudentId
|
|
)
|
|
if (isValidStudentId) {
|
|
val isRepeat:Boolean? by registerViewModel.isRepeat.observeAsState(null)
|
|
when(isRepeat){
|
|
null-> AnimationText(text = registerViewModel.checkRegTip)
|
|
true->
|
|
Text(buildAnnotatedString {
|
|
append(registerViewModel.studentIdDesc)
|
|
withStyle(style = MaterialTheme.typography.body1.toSpanStyle().copy(
|
|
color=MaterialTheme.colors.error)){
|
|
append(studentId)
|
|
}
|
|
append(registerViewModel.registered)
|
|
})
|
|
false->
|
|
Text(buildAnnotatedString {
|
|
append(registerViewModel.studentIdDesc)
|
|
withStyle(style = MaterialTheme.typography.body1.toSpanStyle().copy(
|
|
color=MaterialTheme.colors.primary)){
|
|
append(studentId)
|
|
}
|
|
append(registerViewModel.canRegister)
|
|
})
|
|
}
|
|
}else{
|
|
Text(
|
|
text = registerViewModel.studentIdFormat,
|
|
color = MaterialTheme.colors.error,
|
|
style = MaterialTheme.typography.body1
|
|
)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 淡入淡出并且颜色变化文本
|
|
*
|
|
* @param text
|
|
*/
|
|
@Composable
|
|
fun AnimationText(text:String){
|
|
val infiniteTransition = rememberInfiniteTransition()
|
|
val color by infiniteTransition.animateColor(
|
|
initialValue = Color.Red,
|
|
targetValue = Color.Green,
|
|
animationSpec = infiniteRepeatable(
|
|
animation = tween(1000, easing = LinearEasing),
|
|
repeatMode = RepeatMode.Reverse
|
|
)
|
|
)
|
|
|
|
Text(
|
|
text = text,
|
|
color = color,
|
|
style = MaterialTheme.typography.body1
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 注册弹窗
|
|
*
|
|
* @param registerViewModel
|
|
*/
|
|
@Composable
|
|
fun RegisterDialog(registerViewModel: RegisterViewModel=viewModel()){
|
|
val dialogMsg:DialogMessage? by registerViewModel.dialogMsg.observeAsState(null)
|
|
|
|
val message=dialogMsg?.userResDto?.password
|
|
if(message?.isNotEmpty() == true){
|
|
PasswordDialog(message = message)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 密码弹窗
|
|
*
|
|
* @param registerViewModel
|
|
* @param message
|
|
*/
|
|
@Composable
|
|
fun PasswordDialog(registerViewModel: RegisterViewModel=viewModel(),message:String){
|
|
val button:@Composable () -> Unit = {
|
|
Row(horizontalArrangement=Arrangement.Center,modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(bottom = 10.dp)) {
|
|
OutlinedButton(onClick = { registerViewModel.resetDialogMsg() },
|
|
modifier = Modifier.padding(end = 10.dp)) {
|
|
Text(text = registerViewModel.confirmDesc)
|
|
}
|
|
OutlinedButton(onClick = { TODO() },
|
|
colors = ButtonDefaults.outlinedButtonColors(
|
|
contentColor = MaterialTheme.colors.onBackground)) {
|
|
Text(text = registerViewModel.backDesc)
|
|
}
|
|
}
|
|
}
|
|
AlertDialog(onDismissRequest = { registerViewModel.resetDialogMsg() },
|
|
buttons = button,
|
|
title = { Text(text = registerViewModel.title) },
|
|
text = {
|
|
Text(buildAnnotatedString {
|
|
append(registerViewModel.passwordDialogStart)
|
|
withStyle(style = MaterialTheme.typography.body1.toSpanStyle()
|
|
.copy(color = MaterialTheme.colors.secondary)){
|
|
append(message)
|
|
}
|
|
append(registerViewModel.passwordDialogEnd)
|
|
})
|
|
})
|
|
}
|
|
|
|
|
|
/**
|
|
* 姓名
|
|
*
|
|
* @param registerViewModel
|
|
*/
|
|
@Composable
|
|
fun Name(name:String,registerViewModel: RegisterViewModel=viewModel()){
|
|
Column {
|
|
|
|
val isValidName:Boolean by registerViewModel.isValidName.observeAsState(false)
|
|
val focusManager = LocalFocusManager.current
|
|
OutlinedTextField(value = name,
|
|
onValueChange = {registerViewModel.onNameChange(it)},
|
|
label={ Text(text = registerViewModel.nameDesc)},
|
|
placeholder = { Text(text = registerViewModel.namePlaceholder)},
|
|
singleLine = true,
|
|
isError = !isValidName,
|
|
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
|
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done))
|
|
|
|
if (!isValidName){
|
|
Text(text = registerViewModel.nameFormat,
|
|
color=MaterialTheme.colors.error)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
@Composable
|
|
fun Password(registerViewModel: RegisterViewModel=viewModel()) {
|
|
Text(text = registerViewModel.passwordTip
|
|
,color=MaterialTheme.colors.primary,
|
|
modifier = Modifier.fillMaxWidth())
|
|
}
|
|
|
|
/**
|
|
* 注册按钮
|
|
*
|
|
* @param registerViewModel
|
|
*/
|
|
@Composable
|
|
fun RegisterButton(isValidForm:Boolean,scaffoldState:ScaffoldState,registerViewModel: RegisterViewModel=viewModel()){
|
|
|
|
OutlinedButton(onClick = { registerViewModel.register()},
|
|
enabled = isValidForm,
|
|
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp)) {
|
|
Text(text = registerViewModel.regBtnDesc)
|
|
}
|
|
|
|
OutlinedButton(onClick = { TODO()},
|
|
modifier = Modifier.fillMaxWidth(),
|
|
colors = ButtonDefaults.outlinedButtonColors(
|
|
contentColor = MaterialTheme.colors.onBackground)) {
|
|
Text(text = registerViewModel.backDesc)
|
|
}
|
|
|
|
val snackBarMsg:String by registerViewModel.snackBarMsg.observeAsState("")
|
|
|
|
if(snackBarMsg!=""){
|
|
LaunchedEffect(scaffoldState) {
|
|
scaffoldState.snackbarHostState.showSnackbar(
|
|
message = snackBarMsg
|
|
)
|
|
registerViewModel.resetRegisterResMsg()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
@Preview(showBackground = true)
|
|
|
|
@Composable
|
|
fun DefaultPreview() {
|
|
CSAMSTheme {
|
|
|
|
Row (
|
|
horizontalArrangement=Arrangement.Center,
|
|
verticalAlignment = Alignment.CenterVertically,
|
|
modifier = Modifier.fillMaxSize()) {
|
|
Column(modifier = Modifier.width(IntrinsicSize.Min)) {
|
|
val model=RegisterViewModel()
|
|
|
|
StudentId(model)
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Preview
|
|
@Composable
|
|
fun AnimationTextPreview(){
|
|
AnimationText(text = "6666")
|
|
}
|
|
|
|
@Preview
|
|
@Composable
|
|
fun PasswordDial(){
|
|
CSAMSTheme {
|
|
// A surface container using the 'background' color from the theme
|
|
Surface(color = MaterialTheme.colors.background) {
|
|
// val model=RegisterViewModel()
|
|
// PasswordDialog(registerViewModel=model,message = "99999")
|
|
val openDialog = remember { mutableStateOf(true) }
|
|
AlertDialog(
|
|
onDismissRequest = {
|
|
// Dismiss the dialog when the user clicks outside the dialog or on the back
|
|
// button. If you want to disable that functionality, simply use an empty
|
|
// onCloseRequest.
|
|
openDialog.value = false
|
|
},
|
|
title = {
|
|
Text(text = "Title")
|
|
},
|
|
text = {
|
|
Text(
|
|
"This area typically contains the supportive text " +
|
|
"which presents the details regarding the Dialog's purpose."
|
|
)
|
|
},
|
|
confirmButton = {
|
|
TextButton(
|
|
onClick = {
|
|
openDialog.value = false
|
|
}
|
|
) {
|
|
Text("Confirm")
|
|
}
|
|
},
|
|
dismissButton = {
|
|
TextButton(
|
|
onClick = {
|
|
openDialog.value = false
|
|
}
|
|
) {
|
|
Text("Dismiss")
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
} |