|
|
|
@ -1,8 +1,13 @@ |
|
|
|
|
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 |
|
|
|
@ -10,38 +15,63 @@ 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.Composable |
|
|
|
|
import androidx.compose.runtime.getValue |
|
|
|
|
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.association.ui.AssociationActivity |
|
|
|
|
import com.gyf.csams.module.ActivityPhotoVo |
|
|
|
|
import com.gyf.csams.module.BBSVo |
|
|
|
|
import com.gyf.csams.module.UserInfoVo |
|
|
|
|
import com.gyf.csams.uikit.* |
|
|
|
|
import com.gyf.lib.uikit.MainColumnFrame |
|
|
|
|
import com.gyf.lib.uikit.NavBody |
|
|
|
|
import com.gyf.lib.uikit.ScaffoldModel |
|
|
|
|
import com.gyf.lib.uikit.ShowSnackbar |
|
|
|
|
|
|
|
|
|
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 associationId: Int |
|
|
|
|
get() { |
|
|
|
|
val id = intent.getIntExtra( |
|
|
|
|
AssociationActivity::class.java.name, |
|
|
|
|
0 |
|
|
|
|
) |
|
|
|
|
return if (id == 0) throw IllegalArgumentException("社团id:${id}不合法,初始化失败") else id |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
@ -66,15 +96,15 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
model.clickMenu(ActivityDetailMenu.Info) |
|
|
|
|
} |
|
|
|
|
composable(ActivityDetailMenu.Photo.name) { |
|
|
|
|
Photo() |
|
|
|
|
Photo(nav = nav) |
|
|
|
|
ShowSnackbar(scaffoldState = scaffoldState) |
|
|
|
|
model.clickMenu(ActivityDetailMenu.Photo) |
|
|
|
|
} |
|
|
|
|
composable(ActivityDetailMenu.Member.name) { |
|
|
|
|
Member() |
|
|
|
|
ShowSnackbar(scaffoldState = scaffoldState) |
|
|
|
|
model.clickMenu(ActivityDetailMenu.Member) |
|
|
|
|
} |
|
|
|
|
// composable(ActivityDetailMenu.Member.name) { |
|
|
|
|
// Member() |
|
|
|
|
// ShowSnackbar(scaffoldState = scaffoldState) |
|
|
|
|
// model.clickMenu(ActivityDetailMenu.Member) |
|
|
|
|
// } |
|
|
|
|
composable(ActivityDetailMenu.BBS.name) { |
|
|
|
|
BBS() |
|
|
|
|
ShowSnackbar(scaffoldState = scaffoldState) |
|
|
|
@ -87,32 +117,17 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 底部按钮 |
|
|
|
|
* 活动信息 |
|
|
|
|
* |
|
|
|
|
* @param modifier |
|
|
|
|
*/ |
|
|
|
|
@Composable |
|
|
|
|
private fun BottomButton( |
|
|
|
|
modifier: Modifier = Modifier, |
|
|
|
|
private fun Info( |
|
|
|
|
model: ActivityInfoViewModel = viewModel(), |
|
|
|
|
scaffoldModel: ScaffoldModel = viewModel() |
|
|
|
|
) { |
|
|
|
|
Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { |
|
|
|
|
OutlinedButton(onClick = { model.like { scaffoldModel.update(message = it) } }) { |
|
|
|
|
Text(text = model.like) |
|
|
|
|
} |
|
|
|
|
OutlinedButton(onClick = { model.collect { scaffoldModel.update(message = it) } }) { |
|
|
|
|
Text(text = model.collect) |
|
|
|
|
} |
|
|
|
|
LaunchedEffect(activityId) { |
|
|
|
|
model.load(activityId = activityId) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 活动信息 |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
@Composable |
|
|
|
|
private fun Info() { |
|
|
|
|
MainColumnFrame(background = { |
|
|
|
|
Background( |
|
|
|
|
image = BackgroundImage.ActivityInfo, |
|
|
|
@ -122,7 +137,17 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
RectList(modifier = Modifier.weight(0.4F)) |
|
|
|
|
ActivityDesc(modifier = Modifier.weight(0.4F)) |
|
|
|
|
Spacer(modifier = Modifier.weight(0.05F)) |
|
|
|
|
BottomButton() |
|
|
|
|
BottomButton( |
|
|
|
|
modifier = Modifier.fillMaxWidth(), |
|
|
|
|
confirmDesc = R.string.like_btn, |
|
|
|
|
backDesc = R.string.collect_btn, |
|
|
|
|
onConfirm = { |
|
|
|
|
model.like { scaffoldModel.update(message = it) } |
|
|
|
|
}, |
|
|
|
|
onBack = { |
|
|
|
|
model.collect { scaffoldModel.update(message = it) } |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Spacer(modifier = Modifier.weight(0.05F)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -199,28 +224,106 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
* 相册 |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
@ExperimentalAnimatedInsets |
|
|
|
|
@Composable |
|
|
|
|
private fun Photo( |
|
|
|
|
model: ActivityPhotoViewModel = viewModel(), |
|
|
|
|
scaffoldModel: ScaffoldModel = viewModel() |
|
|
|
|
scaffoldModel: ScaffoldModel = viewModel(), |
|
|
|
|
nav: NavHostController |
|
|
|
|
) { |
|
|
|
|
LaunchedEffect(activityId) { |
|
|
|
|
model.load(activityId = activityId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MainColumnFrame(background = { |
|
|
|
|
Background( |
|
|
|
|
image = BackgroundImage.ActivityPhoto, |
|
|
|
|
alpha = 0.7F |
|
|
|
|
) |
|
|
|
|
}) { |
|
|
|
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) { |
|
|
|
|
IconButton(onClick = { model.upload { scaffoldModel.update(message = it) } }) { |
|
|
|
|
Icon( |
|
|
|
|
painter = painterResource(id = R.drawable.ic_upload), |
|
|
|
|
contentDescription = null |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if (TokenManager.getUserInfo()?.associationVo?.associationId == 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 |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Spacer(modifier = Modifier.height(10.dp)) |
|
|
|
|
|
|
|
|
|
}, 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() |
|
|
|
@ -242,10 +345,18 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
horizontalArrangement = Arrangement.SpaceEvenly |
|
|
|
|
) { |
|
|
|
|
Spacer(modifier = Modifier.weight(0.05F)) |
|
|
|
|
PhotoItem(vo = it[0], modifier = Modifier.weight(0.4F)) |
|
|
|
|
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)) |
|
|
|
|
PhotoItem( |
|
|
|
|
vo = it[1], modifier = Modifier |
|
|
|
|
.weight(0.4F) |
|
|
|
|
.height(PHOTO_HEIGHT) |
|
|
|
|
) |
|
|
|
|
} else { |
|
|
|
|
Spacer(modifier = Modifier.weight(0.4F)) |
|
|
|
|
} |
|
|
|
@ -255,25 +366,35 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Logger.i("totalItemsCount=${listState.layoutInfo.totalItemsCount},firstVisibleItemIndex=${listState.firstVisibleItemIndex}") |
|
|
|
|
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) { |
|
|
|
|
model.loadMore { scaffoldModel.update(message = it) } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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)) |
|
|
|
|
Image( |
|
|
|
|
painter = painterResource(id = R.drawable.ic_launcher_foreground), |
|
|
|
|
contentDescription = null, |
|
|
|
|
painter = photo, |
|
|
|
|
contentDescription = vo.name, |
|
|
|
|
) |
|
|
|
|
when (photo.loadState) { |
|
|
|
|
is ImageLoadState.Loading -> { |
|
|
|
|
// Display a circular progress indicator whilst loading |
|
|
|
|
CircularProgressIndicator(Modifier.align(Alignment.Center)) |
|
|
|
|
} |
|
|
|
|
is ImageLoadState.Error -> { |
|
|
|
|
// If you wish to display some content if the request fails |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -307,6 +428,7 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
painter = painterResource(id = R.drawable.persion_name_border), |
|
|
|
|
contentDescription = null |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
Text(text = first().name) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -377,9 +499,12 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
@Composable |
|
|
|
|
private fun BBS( |
|
|
|
|
model: BBSViewModel = viewModel(), |
|
|
|
|
scaffoldModel: ScaffoldModel = viewModel(), |
|
|
|
|
bbsCommentModel: BBSCommentModel = viewModel() |
|
|
|
|
) { |
|
|
|
|
LaunchedEffect(activityId) { |
|
|
|
|
bbsCommentModel.activityId = this@ActivityDetailActivity.activityId |
|
|
|
|
model.load(activityId) |
|
|
|
|
} |
|
|
|
|
MainColumnFrame(background = { |
|
|
|
|
Background( |
|
|
|
|
image = BackgroundImage.ActivityBBS, |
|
|
|
@ -402,7 +527,9 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SendComment(model = bbsCommentModel) |
|
|
|
|
SendComment(model = bbsCommentModel) { |
|
|
|
|
model.load(activityId) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Box( |
|
|
|
|
modifier = Modifier |
|
|
|
@ -421,9 +548,6 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) { |
|
|
|
|
TODO("加载更多") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
@ -445,8 +569,8 @@ class ActivityDetailActivity : ComponentActivity() { |
|
|
|
|
modifier = Modifier.height(50.dp), |
|
|
|
|
verticalArrangement = Arrangement.SpaceEvenly |
|
|
|
|
) { |
|
|
|
|
Text(text = vo.name) |
|
|
|
|
Text(text = vo.createTime.datetimeFormat()) |
|
|
|
|
Text(text = vo.user.name) |
|
|
|
|
Text(text = Date(vo.createTime).datetimeFormat()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Spacer(modifier = Modifier.weight(0.5F)) |
|
|
|
|