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.
589 lines
23 KiB
589 lines
23 KiB
package com.gyf.csams.association.ui
|
|
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.ManagedActivityResultLauncher
|
|
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.foundation.lazy.LazyColumn
|
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
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.layout.ContentScale
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.tooling.preview.Preview
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.window.PopupProperties
|
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
import androidx.navigation.compose.NavHost
|
|
import androidx.navigation.compose.composable
|
|
import com.gyf.csams.R
|
|
import com.gyf.csams.activity.ui.ApplyActActivity
|
|
import com.gyf.csams.association.model.*
|
|
import com.gyf.csams.uikit.*
|
|
import com.gyf.lib.uikit.*
|
|
import com.gyf.lib.util.TokenManager
|
|
import com.orhanobut.logger.Logger
|
|
import kotlinx.coroutines.delay
|
|
|
|
|
|
/**
|
|
* 社团界面
|
|
*
|
|
*/
|
|
class AssociationActivity : ComponentActivity() {
|
|
|
|
private val associationId: Int
|
|
get() {
|
|
val id = intent.getIntExtra(
|
|
AssociationActivity::class.java.name,
|
|
0
|
|
)
|
|
return if (id == 0) throw IllegalArgumentException("社团id:${id}不合法,初始化失败") else id
|
|
}
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContent {
|
|
|
|
NavBody { nav, scaffoldState ->
|
|
val model: AssociationViewModel = viewModel()
|
|
val currentMenuName: AssociationMenu by model.currentMenu.observeAsState(
|
|
AssociationMenu.startMenu
|
|
)
|
|
|
|
val expanded by model.expanded.observeAsState(false)
|
|
|
|
//TODO重命名操作反馈
|
|
val rename =
|
|
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
|
if (it.resultCode == RESULT_OK) {
|
|
val m = it.data?.getStringExtra(RenameActivity::class.java.name)
|
|
Logger.i("社团重命名返回:${m}")
|
|
model.update(message = m)
|
|
}
|
|
}
|
|
val examResult =
|
|
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
|
if (it.resultCode == RESULT_OK) {
|
|
val m = it.data?.getStringExtra(ExamActivity::class.java.name)
|
|
Logger.i("试卷提交结果:${m}")
|
|
model.update(message = m)
|
|
}
|
|
}
|
|
|
|
Column {
|
|
TextTopAppBar(nav = nav,
|
|
currentMenuName = currentMenuName.menuName,
|
|
menuNames = AssociationMenu.values(),
|
|
iconMenu = { model.switchType() }) {
|
|
Row {
|
|
|
|
|
|
DropdownMenu(
|
|
expanded = expanded,
|
|
onDismissRequest = { },
|
|
properties = PopupProperties()
|
|
) {
|
|
when {
|
|
TokenManager.getUserInfo()?.associationVo?.associationId == associationId && TokenManager.getUserInfo()?.isHead == true -> {
|
|
DropdownMenuItem(onClick = {
|
|
|
|
startActivity(
|
|
Intent(
|
|
this@AssociationActivity,
|
|
ApplyActActivity::class.java
|
|
).apply {
|
|
putExtra(
|
|
AssociationActivity::class.java.name,
|
|
associationId
|
|
)
|
|
}
|
|
)
|
|
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Text(text = getString(R.string.apply_act_menu))
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_add_fill),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
DropdownMenuItem(onClick = {
|
|
startActivity(
|
|
Intent(
|
|
this@AssociationActivity,
|
|
ExamActivity::class.java
|
|
).apply {
|
|
putExtra(
|
|
AssociationActivity::class.java.name,
|
|
associationId
|
|
)
|
|
putExtra(
|
|
ExamActivityType::name.name,
|
|
ExamActivityType.SET_EXAM
|
|
)
|
|
})
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Text(text = getString(R.string.set_exam_menu))
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_editor),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
DropdownMenuItem(onClick = {
|
|
startActivity(
|
|
Intent(
|
|
this@AssociationActivity,
|
|
AuditJoinActivity::class.java
|
|
).apply {
|
|
putExtra(
|
|
AssociationActivity::class.java.name,
|
|
associationId
|
|
)
|
|
})
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Text(text = ("入团审核"))
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_exchange_rate),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
DropdownMenuItem(onClick = {
|
|
rename.launch(Intent(
|
|
this@AssociationActivity,
|
|
RenameActivity::class.java
|
|
).apply {
|
|
putExtra(
|
|
AssociationActivity::class.java.name,
|
|
associationId
|
|
)
|
|
})
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Text(text = getString(R.string.rename_menu))
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_exchange_rate),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
|
|
}
|
|
TokenManager.getUserInfo()?.associationVo == null -> DropdownMenuItem(
|
|
onClick = {
|
|
model.applyAssociation(associationId = associationId) {
|
|
model.update(applyAssociationResultVo = it)
|
|
}
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Text(text = getString(R.string.join_association))
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_add_account),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
}
|
|
DropdownMenuItem(onClick = {
|
|
model.close()
|
|
}) {
|
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_arrow_up),
|
|
contentDescription = null,
|
|
modifier = Modifier
|
|
.height(30.dp)
|
|
.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NavHost(
|
|
navController = nav,
|
|
startDestination = AssociationMenu.startMenu.name
|
|
) {
|
|
composable(AssociationMenu.Member.name) {
|
|
model.clickMenu(AssociationMenu.Member)
|
|
Member()
|
|
ShowTip(model = model, examResult = examResult)
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
}
|
|
composable(AssociationMenu.Main.name) {
|
|
model.clickMenu(AssociationMenu.Main)
|
|
Main()
|
|
ShowTip(model = model, examResult = examResult)
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
}
|
|
composable(AssociationMenu.ActivityList.name) {
|
|
model.clickMenu(AssociationMenu.ActivityList)
|
|
AssociationList()
|
|
ShowTip(model = model, examResult = examResult)
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 显示提示
|
|
*
|
|
* @param model
|
|
* @param examResult
|
|
*/
|
|
@Composable
|
|
private fun ShowTip(
|
|
model: AssociationViewModel = viewModel(),
|
|
examResult: ManagedActivityResultLauncher<Intent, *>
|
|
) {
|
|
val scaffoldModel: ScaffoldModel = viewModel()
|
|
val message by model.dropMenuMessage.observeAsState()
|
|
message?.let {
|
|
scaffoldModel.update(message = message, actionLabel = "刷新")
|
|
|
|
val s by scaffoldModel.data.observeAsState()
|
|
if (s == null) {
|
|
model.update(message = null)
|
|
}
|
|
LaunchedEffect(message) {
|
|
delay(it.length * 300L)
|
|
model.update(message = null)
|
|
}
|
|
}
|
|
val applyAssociationResultVo by model.applyAssociationResultVo.observeAsState()
|
|
applyAssociationResultVo?.let {
|
|
when {
|
|
it.result == true && it.hasPaper == true ->
|
|
scaffoldModel.update(
|
|
message = "申请此社团需要完成一份笔试题,点击确认获取试卷",
|
|
actionLabel = "确认"
|
|
) {
|
|
examResult.launch(
|
|
Intent(
|
|
this@AssociationActivity,
|
|
ExamActivity::class.java
|
|
).apply {
|
|
putExtra(AssociationActivity::class.java.name, associationId)
|
|
putExtra(
|
|
ExamActivityType::name.name,
|
|
ExamActivityType.JOIN_Association
|
|
)
|
|
})
|
|
|
|
}
|
|
it.result == true ->
|
|
scaffoldModel.update(
|
|
message = "入团申请发送成功,请耐心等待审核结果",
|
|
actionLabel = "收到"
|
|
)
|
|
|
|
it.associationVo != null ->
|
|
scaffoldModel.update(
|
|
message = "您已申请进入${it.associationVo?.name},请耐心等待审核结果",
|
|
actionLabel = "收到"
|
|
)
|
|
|
|
else ->
|
|
scaffoldModel.update(
|
|
message = "入团申请发送失败!",
|
|
actionLabel = "确认"
|
|
)
|
|
}
|
|
model.update(applyAssociationResultVo = null)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 社团成员
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun Member() {
|
|
MainColumnFrame(background = { Background(image = BackgroundImage.AssociationMain) }) {
|
|
val searchWeight = 0.2F
|
|
Search(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(searchWeight)
|
|
)
|
|
MemberList(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(1 - searchWeight)
|
|
)
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检索成员
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun Search(
|
|
modifier: Modifier = Modifier,
|
|
model: MemberViewModel = viewModel()
|
|
) {
|
|
Column(modifier = modifier.fillMaxSize()) {
|
|
Spacer(modifier = Modifier.weight(0.5F))
|
|
Row(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(0.5F), verticalAlignment = Alignment.CenterVertically
|
|
) {
|
|
|
|
val textFieldWeight = 0.4F
|
|
val buttonWeight = 0.2F
|
|
val spaceWeight = (1 - textFieldWeight - buttonWeight) / 3
|
|
Spacer(modifier = Modifier.weight((spaceWeight)))
|
|
BaseTextField(
|
|
modifier = Modifier.weight(textFieldWeight),
|
|
form = model.name,
|
|
singeLine = true
|
|
)
|
|
Spacer(modifier = Modifier.weight(spaceWeight))
|
|
OutlinedButton(
|
|
onClick = {
|
|
model.load(associationId)
|
|
},
|
|
modifier = Modifier.weight(buttonWeight)
|
|
) {
|
|
Text(text = stringResource(id = R.string.search_btn))
|
|
}
|
|
Spacer(modifier = Modifier.weight(spaceWeight))
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 成员列表
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun MemberList(
|
|
modifier: Modifier = Modifier,
|
|
model: MemberViewModel = viewModel()
|
|
) {
|
|
model.load(associationId)
|
|
val data by model.data.observeAsState()
|
|
val listState = rememberLazyListState()
|
|
LazyColumn(
|
|
state = listState, modifier = modifier, verticalArrangement =
|
|
Arrangement.spacedBy(space = 10.dp, alignment = Alignment.CenterVertically)
|
|
) {
|
|
data?.forEach {
|
|
item {
|
|
Profile(modifier = Modifier.height(300.dp), personInfoVo = it, readOnly = true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 社团主页
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun Main(model: AssociationViewModel = viewModel()) {
|
|
LaunchedEffect(associationId) {
|
|
model.load(associationId)
|
|
}
|
|
MainColumnFrame(background = {
|
|
Background(image = BackgroundImage.AssociationMain, alpha = 0.7F)
|
|
}) {
|
|
val nameW = 0.1F
|
|
val cardW = 0.66F * 0.4F
|
|
Name(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(nameW)
|
|
)
|
|
val associationVo by model.associationVo.observeAsState()
|
|
associationVo?.associationVo?.desc?.let {
|
|
DescCard(
|
|
modifier = Modifier
|
|
.weight(cardW)
|
|
.fillMaxWidth(),
|
|
content = it
|
|
)
|
|
}
|
|
Commander(
|
|
modifier = Modifier.weight(cardW)
|
|
)
|
|
Showcase(modifier = Modifier.weight(1F - nameW - cardW - cardW))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 社团名字
|
|
*
|
|
* @param modifier
|
|
*/
|
|
@Composable
|
|
private fun Name(modifier: Modifier, model: AssociationViewModel = viewModel()) {
|
|
val associationVo by model.associationVo.observeAsState()
|
|
Box(modifier = modifier) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.association_name_border),
|
|
contentDescription = null,
|
|
contentScale = ContentScale.FillBounds,
|
|
modifier = Modifier.fillMaxSize()
|
|
)
|
|
Column {
|
|
Spacer(modifier = Modifier.weight(1.7F / 3))
|
|
Row(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(1F / 3),
|
|
horizontalArrangement = Arrangement.Center
|
|
) {
|
|
associationVo?.associationVo?.name?.let { Text(text = it) }
|
|
}
|
|
Spacer(modifier = Modifier.weight(0.3F / 3))
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 团长名字
|
|
*
|
|
* @param modifier
|
|
*/
|
|
@Composable
|
|
private fun Commander(modifier: Modifier, model: AssociationViewModel = viewModel()) {
|
|
Box(modifier = modifier, contentAlignment = Alignment.Center) {
|
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
|
|
|
Image(
|
|
painter = painterResource(id = R.drawable.persion_name_border),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
val info by model.associationVo.observeAsState()
|
|
info?.head?.let {
|
|
Text(text = it.name)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 风采展示区
|
|
*
|
|
* @param modifier
|
|
*/
|
|
@Composable
|
|
private fun Showcase(modifier: Modifier) {
|
|
Box(modifier = modifier, contentAlignment = Alignment.Center) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.showcase_border),
|
|
contentDescription = null,
|
|
modifier = Modifier.fillMaxSize()
|
|
)
|
|
Image(
|
|
painter = painterResource(id = R.drawable.ic_launcher_foreground),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 活动列表
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun AssociationList() {
|
|
MainColumnFrame(background = {
|
|
Background(
|
|
image = BackgroundImage.AssociationMain,
|
|
alpha = 07F
|
|
)
|
|
}) {
|
|
HistoryActivityList(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.border(width = 1.dp, color = MaterialTheme.colors.onBackground)
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 进行中的活动
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun OngoingActivity(
|
|
modifier: Modifier = Modifier
|
|
) {
|
|
Row(modifier = modifier, horizontalArrangement = Arrangement.Center) {
|
|
val weight = 0.5F
|
|
val spaceWeight = (1 - 0.5F) / 2
|
|
Spacer(modifier = Modifier.weight(spaceWeight))
|
|
Poster(modifier = Modifier.weight(weight))
|
|
Spacer(modifier = Modifier.weight(spaceWeight))
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 历史活动列表
|
|
*
|
|
* @param modifier
|
|
*/
|
|
@Composable
|
|
private fun HistoryActivityList(
|
|
modifier: Modifier,
|
|
model: HistoryActViewModel = viewModel()
|
|
) {
|
|
LaunchedEffect(associationId) {
|
|
model.load(associationId = associationId)
|
|
}
|
|
|
|
val list by model.data.observeAsState()
|
|
if (list?.size == 0) {
|
|
Row(modifier = Modifier.fillMaxWidth()) {
|
|
Text(text = "目前社团没有任何活动")
|
|
}
|
|
} else {
|
|
Activities(list = list, modifier = modifier)
|
|
}
|
|
|
|
}
|
|
|
|
@Preview
|
|
@Composable
|
|
fun NamePreview() {
|
|
Divider(color = MaterialTheme.colors.background)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|