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.
595 lines
22 KiB
595 lines
22 KiB
package com.gyf.csams.activity.ui
|
|
|
|
import android.content.Intent
|
|
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.Canvas
|
|
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.unit.dp
|
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
import androidx.navigation.NavHostController
|
|
import androidx.navigation.compose.NavHost
|
|
import androidx.navigation.compose.composable
|
|
import com.google.accompanist.coil.rememberCoilPainter
|
|
import com.google.accompanist.imageloading.ImageLoadState
|
|
import com.google.accompanist.insets.ExperimentalAnimatedInsets
|
|
import com.google.accompanist.insets.navigationBarsWithImePadding
|
|
import com.gyf.csams.R
|
|
import com.gyf.csams.activity.model.*
|
|
import com.gyf.csams.module.ActivityPhotoVo
|
|
import com.gyf.csams.module.BBSVo
|
|
import com.gyf.csams.module.TendencyType
|
|
import com.gyf.csams.module.UserInfoVo
|
|
import com.gyf.csams.uikit.*
|
|
import com.gyf.lib.uikit.*
|
|
import com.gyf.lib.util.Api
|
|
import com.gyf.lib.util.BottomButton
|
|
import com.gyf.lib.util.DateTimeUtil.datetimeFormat
|
|
import com.gyf.lib.util.TokenManager
|
|
import com.orhanobut.logger.Logger
|
|
import java.util.*
|
|
|
|
|
|
val PHOTO_HEIGHT = 200.dp
|
|
/**
|
|
* 活动详情
|
|
*
|
|
*/
|
|
class ActivityDetailActivity : ComponentActivity() {
|
|
|
|
|
|
private val activityId: Int
|
|
get() {
|
|
val id = intent.getIntExtra(
|
|
ActivityDetailActivity::class.java.name,
|
|
0
|
|
)
|
|
return if (id == 0) throw IllegalArgumentException("活动id:${id}不合法,初始化失败") else id
|
|
}
|
|
|
|
@ExperimentalAnimatedInsets
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
|
|
setContent {
|
|
NavBody { nav, scaffoldState ->
|
|
val model: ActivityDetailViewModel = viewModel()
|
|
val currentMenuName by model.currentMenu.observeAsState(ActivityDetailMenu.startMenu)
|
|
Column {
|
|
TextTopAppBar(
|
|
nav = nav,
|
|
currentMenuName = currentMenuName.menuName,
|
|
menuNames = ActivityDetailMenu.values()
|
|
)
|
|
NavHost(
|
|
navController = nav,
|
|
startDestination = ActivityDetailMenu.startMenu.name
|
|
) {
|
|
composable(ActivityDetailMenu.Info.name) {
|
|
Info()
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
model.clickMenu(ActivityDetailMenu.Info)
|
|
}
|
|
composable(ActivityDetailMenu.Photo.name) {
|
|
Photo(nav = nav)
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
model.clickMenu(ActivityDetailMenu.Photo)
|
|
}
|
|
// composable(ActivityDetailMenu.Member.name) {
|
|
// Member()
|
|
// ShowSnackbar(scaffoldState = scaffoldState)
|
|
// model.clickMenu(ActivityDetailMenu.Member)
|
|
// }
|
|
composable(ActivityDetailMenu.BBS.name) {
|
|
BBS()
|
|
ShowSnackbar(scaffoldState = scaffoldState)
|
|
model.clickMenu(ActivityDetailMenu.BBS)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 活动信息
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun Info(
|
|
model: ActivityInfoViewModel = viewModel(),
|
|
scaffoldModel: ScaffoldModel = viewModel()
|
|
) {
|
|
LaunchedEffect(activityId) {
|
|
model.load(activityId = activityId)
|
|
model.checkTendency(activityId = activityId)
|
|
}
|
|
MainColumnFrame(background = {
|
|
Background(
|
|
image = BackgroundImage.ActivityInfo,
|
|
alpha = 0.7F
|
|
)
|
|
}) {
|
|
RectList(modifier = Modifier.weight(0.4F))
|
|
ActivityDesc(modifier = Modifier.weight(0.4F))
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
val checkTendency by model.tendency.observeAsState()
|
|
checkTendency?.apply {
|
|
val confirmDesc = if (hasLike) R.string.cancel_like else R.string.like_btn
|
|
val backDesc = if (hasCollect) R.string.cancel_collect else R.string.collect_btn
|
|
BottomButton(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
confirmDesc = confirmDesc,
|
|
backDesc = backDesc,
|
|
onConfirm = {
|
|
model.tendency(type = TendencyType.Like, activityId = activityId) {
|
|
scaffoldModel.update(
|
|
message = "${getString(confirmDesc)}${if (it) "成功" else "失败"}",
|
|
"确认"
|
|
)
|
|
model.checkTendency(activityId = activityId)
|
|
}
|
|
},
|
|
onBack = {
|
|
model.tendency(type = TendencyType.Collect, activityId = activityId) {
|
|
scaffoldModel.update(
|
|
message = "${getString(backDesc)}${if (it) "成功" else "失败"}",
|
|
"确认"
|
|
)
|
|
model.checkTendency(activityId = activityId)
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 活动基础信息
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun RectList(
|
|
modifier: Modifier = Modifier,
|
|
model: ActivityInfoViewModel = viewModel()
|
|
) {
|
|
val activityDetailVo by model.activityDetailVo.observeAsState()
|
|
activityDetailVo?.let {
|
|
Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
|
|
Column(
|
|
modifier = Modifier.fillMaxSize(),
|
|
verticalArrangement = Arrangement.SpaceAround
|
|
) {
|
|
RectListItem(text = it.associationVo.name)
|
|
RectListItem(text = it.activityVo.activityName)
|
|
RectListItem(text = Date(it.activityVo.activityTime).datetimeFormat())
|
|
RectListItem(text = it.activityVo.activityAddress)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 列表项
|
|
*
|
|
* @param text
|
|
*/
|
|
@Composable
|
|
private fun RectListItem(text: String) {
|
|
Row(modifier = Modifier.fillMaxWidth()) {
|
|
val color = MaterialTheme.colors.secondaryVariant
|
|
val canvasSize = 30.dp
|
|
Box(modifier = Modifier.weight(0.5F), contentAlignment = Alignment.Center) {
|
|
Canvas(modifier = Modifier.size(canvasSize)) {
|
|
drawCircle(color = color)
|
|
}
|
|
}
|
|
Text(text = text, style = MaterialTheme.typography.h5, modifier = Modifier.weight(0.5F))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 活动介绍
|
|
*
|
|
* @param modifier
|
|
* @param model
|
|
*/
|
|
@Composable
|
|
private fun ActivityDesc(
|
|
modifier: Modifier = Modifier,
|
|
model: ActivityInfoViewModel = viewModel()
|
|
) {
|
|
Column(modifier = modifier) {
|
|
val activityDetailVo by model.activityDetailVo.observeAsState()
|
|
activityDetailVo?.let {
|
|
DescCard(
|
|
modifier = Modifier.weight(0.5F),
|
|
content = it.activityVo.activityDesc
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 相册
|
|
*
|
|
*/
|
|
@ExperimentalAnimatedInsets
|
|
@Composable
|
|
private fun Photo(
|
|
model: ActivityPhotoViewModel = viewModel(),
|
|
infoModel: ActivityInfoViewModel = viewModel(),
|
|
scaffoldModel: ScaffoldModel = viewModel(),
|
|
nav: NavHostController
|
|
) {
|
|
LaunchedEffect(activityId) {
|
|
model.load(activityId = activityId)
|
|
}
|
|
|
|
MainColumnFrame(background = {
|
|
Background(
|
|
image = BackgroundImage.ActivityPhoto,
|
|
alpha = 0.7F
|
|
)
|
|
}) {
|
|
val activityDetailVo by infoModel.activityDetailVo.observeAsState()
|
|
if (TokenManager.getUserInfo()?.associationVo?.associationId == activityDetailVo?.associationVo?.associationId && TokenManager.getUserInfo()?.isHead == true) {
|
|
var photoUri: Uri? by remember {
|
|
mutableStateOf(null)
|
|
}
|
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
|
|
|
val resultLauncher =
|
|
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
|
when (it.resultCode) {
|
|
RESULT_OK -> {
|
|
it.data?.data?.apply {
|
|
Logger.i("uri=$this")
|
|
photoUri = this
|
|
}
|
|
}
|
|
}
|
|
}
|
|
IconButton(onClick = {
|
|
resultLauncher.launch(
|
|
Intent(
|
|
Intent.ACTION_PICK,
|
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
|
)
|
|
)
|
|
}) {
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_upload),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
|
|
photoUri?.let {
|
|
val status by model.name.statusForm.observeAsState()
|
|
AlertDialog(onDismissRequest = { /*TODO*/ }, title = {
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
horizontalArrangement = Arrangement.Center
|
|
) {
|
|
Text(text = "上传照片")
|
|
}
|
|
}, text = {
|
|
|
|
val photo = rememberCoilPainter(request = it)
|
|
Column {
|
|
BaseTextField(
|
|
modifier = Modifier.navigationBarsWithImePadding(),
|
|
form = model.name
|
|
)
|
|
Image(
|
|
// modifier=Modifier.weight(0.5F),
|
|
painter = photo,
|
|
contentDescription = null,
|
|
contentScale = ContentScale.Inside
|
|
)
|
|
}
|
|
|
|
|
|
}, buttons = {
|
|
BottomButton(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
confirmDesc = R.string.upload_btn,
|
|
backDesc = R.string.close_btn,
|
|
onConfirm = {
|
|
model.upload(activityId = activityId, uri = it) {
|
|
photoUri = null
|
|
scaffoldModel.update(it, actionLabel = "关闭提示") {
|
|
nav.navigate(ActivityDetailMenu.Photo.name)
|
|
}
|
|
}
|
|
},
|
|
onBack = {
|
|
photoUri = null
|
|
},
|
|
enabled = status == FormStatus.Valid
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
}
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.padding(10.dp)
|
|
.border(
|
|
width = 1.dp,
|
|
color = MaterialTheme.colors.background
|
|
)
|
|
) {
|
|
val listState = rememberLazyListState()
|
|
val photos by model.data.observeAsState()
|
|
photos?.let {
|
|
LazyColumn(state = listState) {
|
|
it.chunked(2).forEach {
|
|
item {
|
|
Spacer(modifier = Modifier.height(20.dp))
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
horizontalArrangement = Arrangement.SpaceEvenly
|
|
) {
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
PhotoItem(
|
|
vo = it[0], modifier = Modifier
|
|
.weight(0.4F)
|
|
.height(PHOTO_HEIGHT)
|
|
)
|
|
Spacer(modifier = Modifier.weight(0.1F))
|
|
if (it.size == 2) {
|
|
PhotoItem(
|
|
vo = it[1], modifier = Modifier
|
|
.weight(0.4F)
|
|
.height(PHOTO_HEIGHT)
|
|
)
|
|
} else {
|
|
Spacer(modifier = Modifier.weight(0.4F))
|
|
}
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
}
|
|
Spacer(modifier = Modifier.height(20.dp))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Composable
|
|
private fun PhotoItem(modifier: Modifier = Modifier, vo: ActivityPhotoVo) {
|
|
Box(
|
|
modifier = modifier.border(width = 1.dp, color = MaterialTheme.colors.onBackground),
|
|
contentAlignment = Alignment.Center
|
|
) {
|
|
val photo = rememberCoilPainter(request = Api.buildUrl(vo.url))
|
|
|
|
when (photo.loadState) {
|
|
is ImageLoadState.Loading -> CircularProgressIndicator(Modifier.align(Alignment.Center))
|
|
is ImageLoadState.Success -> Image(
|
|
painter = photo,
|
|
contentDescription = vo.name,
|
|
)
|
|
else -> Text(text = "图片加载失败")
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 活动成员
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun Member(
|
|
model: ActivityMemberViewModel = viewModel()
|
|
) {
|
|
MainColumnFrame(background = {
|
|
Background(
|
|
image = BackgroundImage.ActivityMember,
|
|
alpha = 0.7F
|
|
)
|
|
}) {
|
|
|
|
val data by model.data.observeAsState()
|
|
|
|
data?.apply {
|
|
Spacer(modifier = Modifier.height(5.dp))
|
|
Row(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(0.2F), horizontalArrangement = Arrangement.Center
|
|
) {
|
|
Box(contentAlignment = Alignment.Center) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.persion_name_border),
|
|
contentDescription = null
|
|
)
|
|
|
|
Text(text = first().name)
|
|
}
|
|
}
|
|
Spacer(modifier = Modifier.height(5.dp))
|
|
|
|
|
|
Box(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.weight(0.8F)
|
|
.padding(10.dp)
|
|
.border(width = 1.dp, color = MaterialTheme.colors.onBackground)
|
|
) {
|
|
val listState = rememberLazyListState()
|
|
drop(1).let {
|
|
LazyColumn(state = listState) {
|
|
it.chunked(2).forEach {
|
|
item {
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
Row(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
horizontalArrangement = Arrangement.SpaceEvenly
|
|
) {
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
Participant(vo = it[0], modifier = Modifier.weight(0.4F))
|
|
Spacer(modifier = Modifier.weight(0.1F))
|
|
if (it.size == 2) {
|
|
Participant(
|
|
vo = it[1],
|
|
modifier = Modifier.weight(0.4F)
|
|
)
|
|
} else {
|
|
Spacer(modifier = Modifier.weight(0.4F))
|
|
}
|
|
Spacer(modifier = Modifier.weight(0.05F))
|
|
}
|
|
Spacer(modifier = Modifier.height(10.dp))
|
|
}
|
|
}
|
|
}
|
|
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
|
|
TODO("加载更多")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun Participant(modifier: Modifier = Modifier, vo: UserInfoVo) {
|
|
Box(modifier = modifier, contentAlignment = Alignment.Center) {
|
|
Image(
|
|
painter = painterResource(id = R.drawable.participant_border),
|
|
contentDescription = null,
|
|
// contentScale = ContentScale.FillBounds,
|
|
// modifier = Modifier.fillMaxSize()
|
|
)
|
|
Text(text = vo.name)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 交流区
|
|
*
|
|
*/
|
|
@Composable
|
|
private fun BBS(
|
|
model: BBSViewModel = viewModel(),
|
|
bbsCommentModel: BBSCommentModel = viewModel()
|
|
) {
|
|
LaunchedEffect(activityId) {
|
|
bbsCommentModel.activityId = this@ActivityDetailActivity.activityId
|
|
model.load(activityId)
|
|
}
|
|
MainColumnFrame(background = {
|
|
Background(
|
|
image = BackgroundImage.ActivityBBS,
|
|
alpha = 0.7F
|
|
)
|
|
}) {
|
|
|
|
Row(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(horizontal = 10.dp),
|
|
horizontalArrangement = Arrangement.End,
|
|
verticalAlignment = Alignment.CenterVertically
|
|
) {
|
|
IconButton(onClick = { bbsCommentModel.openDialog() }) {
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.ic_editor),
|
|
contentDescription = null
|
|
)
|
|
}
|
|
}
|
|
|
|
SendComment(model = bbsCommentModel) {
|
|
model.load(activityId)
|
|
}
|
|
|
|
Box(
|
|
modifier = Modifier
|
|
.weight(0.9F)
|
|
.padding(10.dp)
|
|
.border(width = 1.dp, color = MaterialTheme.colors.onBackground)
|
|
) {
|
|
val listState = rememberLazyListState()
|
|
val data by model.data.observeAsState()
|
|
LazyColumn(state = listState) {
|
|
data?.forEach {
|
|
item {
|
|
BBSItem(vo = it)
|
|
Spacer(modifier = Modifier.height(5.dp))
|
|
Divider(color = MaterialTheme.colors.onBackground)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun BBSItem(vo: BBSVo) {
|
|
Column {
|
|
Row(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.padding(10.dp)
|
|
) {
|
|
Card(
|
|
backgroundColor = MaterialTheme.colors.secondaryVariant,
|
|
modifier = Modifier.weight(0.5F)
|
|
) {
|
|
Column(
|
|
modifier = Modifier.height(50.dp),
|
|
verticalArrangement = Arrangement.SpaceEvenly
|
|
) {
|
|
Text(text = vo.user.name)
|
|
Text(text = Date(vo.createTime).datetimeFormat())
|
|
}
|
|
}
|
|
Spacer(modifier = Modifier.weight(0.5F))
|
|
}
|
|
|
|
Card(
|
|
backgroundColor = MaterialTheme.colors.background,
|
|
modifier = Modifier.padding(10.dp)
|
|
) {
|
|
Text(
|
|
text = vo.content, modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(100.dp)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
} |