package com.gyf.csams.association.ui import android.Manifest import android.app.Activity import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle import android.provider.MediaStore import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.Image import androidx.compose.foundation.border import androidx.compose.foundation.layout.* import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.OutlinedButton import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.lifecycle.viewmodel.compose.viewModel import com.google.accompanist.coil.rememberCoilPainter import com.gyf.csams.R import com.gyf.csams.association.model.RegAssociationViewModel import com.gyf.csams.uikit.Background import com.gyf.csams.uikit.BackgroundImage import com.gyf.lib.uikit.* import com.gyf.lib.util.BottomButton import com.gyf.lib.util.CheckStatus import com.gyf.lib.util.format import com.orhanobut.logger.Logger import java.util.* /** * 注册社团 * */ class RegAssociationActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Body { MainColumnFrame(background = { Background( BackgroundImage.RegAssociation, alpha = 0.5F ) }) { Spacer( modifier = Modifier .weight(0.1F) ) Title() Tip() Name() Desc( modifier = Modifier .weight(0.1F) .fillMaxWidth() ) Spacer(modifier = Modifier.weight(0.05F)) Logo( modifier = Modifier .weight(0.2F) .fillMaxWidth() ) Spacer(modifier = Modifier.weight(0.05F)) val model: RegAssociationViewModel = viewModel() val scaffoldModel: ScaffoldModel = viewModel() val name by model.name.statusForm.observeAsState() val desc by model.name.statusForm.observeAsState() val fileId by model.fileId.observeAsState() val checkInfo by model.checkInfo.observeAsState() BottomButton( modifier = Modifier.fillMaxWidth(), enabled = name == FormStatus.Valid && desc == FormStatus.Valid && fileId != null, confirmDesc = if (checkInfo != null) R.string.reg_again_btn else R.string.reg_btn, ) { model.register { scaffoldModel.update(message = it, actionLabel = "返回") { finish() } } } Spacer(modifier = Modifier.weight(0.05F)) } } } } @Composable private fun Tip(model: RegAssociationViewModel = viewModel()) { val checkInfo by model.checkInfo.observeAsState() checkInfo?.let { Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) { when (val status = it.checkStatus) { CheckStatus.Finish -> Text(buildAnnotatedString { withStyle(style = MaterialTheme.typography.h5.toParagraphStyle()) { append("您于${Date(it.applyTime).format()}提交的${model.frameDesc}审核不通过原因如下:\n") } withStyle( style = MaterialTheme.typography.h6.copy(color = MaterialTheme.colors.error) .toParagraphStyle() ) { append("初审意见:${it.firstCause}\n") it.lastCause?.let { append("复审意见:${it}") } } }) else -> { Text( text = status.desc, style = MaterialTheme.typography.h5.copy(color = MaterialTheme.colors.primary) ) } } } } } @Preview @Composable private fun TestPreview9() { Text(text = "123", color = MaterialTheme.colors.error) } /** * 社团Logo * * @param modifier */ @Composable private fun Logo( model: RegAssociationViewModel = viewModel(), scaffoldModel: ScaffoldModel = viewModel(), modifier: Modifier ) { val photoIntent = Intent( Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI ) val uri: Uri? by model.picture.observeAsState() val resultLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { when (it.resultCode) { Activity.RESULT_OK -> { it.data?.data?.apply { Logger.i("uri=$this") model.setPicture(this) } } } } val loadPicture = { //model.loadPicture(context) resultLauncher.launch(photoIntent) } val launcher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> if (isGranted) { // Permission Accepted: Do something loadPicture() } else { // Permission Denied: Do something scaffoldModel.update(message = getString(R.string.denined_photo_permission)) } } Box(contentAlignment = Alignment.Center, modifier = modifier) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, modifier = Modifier .fillMaxSize() .border(width = 1.dp, color = MaterialTheme.colors.onBackground) ) { if (uri == null) { OutlinedButton(onClick = { when (PackageManager.PERMISSION_GRANTED) { ContextCompat.checkSelfPermission( applicationContext, Manifest.permission.READ_EXTERNAL_STORAGE ) -> { // Some works that require permission loadPicture() } else -> { // Asking for permission launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) } } }) { Text(text = model.picturePlaceHolder) } } else { uri.let { it -> if (it != null) { Row { val logo = rememberCoilPainter(request = uri) Image( painter = logo, contentDescription = null ) val checkInfo by model.checkInfo.observeAsState() if (checkInfo == null || checkInfo?.checkStatus == CheckStatus.Finish) { Column( modifier = Modifier.fillMaxHeight(), verticalArrangement = Arrangement.SpaceEvenly ) { IconButton(onClick = { loadPicture() }) { Image( painter = painterResource(id = R.drawable.ic_exchange_rate), contentDescription = null ) } IconButton(onClick = { scaffoldModel.update("确认上传此图片?", actionLabel = "确定") { Logger.i("开始上传") model.uploadPhoto { scaffoldModel.update( message = it, actionLabel = "关闭提示" ) } } }) { Image( painter = painterResource(id = R.drawable.ic_upload), contentDescription = null ) } } } } } else { Text(text = model.errorPicture) } } } } } } /** * 菜单标题 * */ @Composable private fun Title(model: RegAssociationViewModel = viewModel()) { Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) { Text(text = model.frameDesc, style = MaterialTheme.typography.h4) } } /** * 社团名称 * @param model */ @Composable private fun Name(model: RegAssociationViewModel = viewModel()) { val checkInfo by model.checkInfo.observeAsState() BaseTextField( form = model.name, singeLine = true, modifier = Modifier.fillMaxWidth(), readOnly = checkInfo?.checkStatus != CheckStatus.Finish ) } /** * 社团简介 * @param model */ @Composable private fun Desc(model: RegAssociationViewModel = viewModel(), modifier: Modifier) { val checkInfo by model.checkInfo.observeAsState() BaseTextField( form = model.desc, modifier = modifier, readOnly = checkInfo?.checkStatus != CheckStatus.Finish ) } }