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.

587 lines
20 KiB

package com.gyf.csams.main.ui
import android.content.Intent
import android.os.Bundle
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.clickable
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.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
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.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.PagerState
import com.google.accompanist.pager.rememberPagerState
import com.gyf.csams.R
import com.gyf.csams.account.model.AccountViewModel
import com.gyf.csams.activity.ui.ActivityDetailActivity
import com.gyf.csams.activity.ui.TendencyActivity
import com.gyf.csams.association.ui.AssociationActivity
import com.gyf.csams.association.ui.RegAssociationActivity
import com.gyf.csams.main.model.*
import com.gyf.csams.message.ui.SysMessageActivity
import com.gyf.csams.module.*
import com.gyf.csams.uikit.*
import com.gyf.lib.model.RefreshViewModel
import com.gyf.lib.service.BaseActivity
import com.gyf.lib.uikit.*
import com.gyf.lib.util.*
import com.orhanobut.logger.Logger
/**
* 主界面
*
*/
class MainActivity : BaseActivity() {
override val clientType: ClientType = ClientType.Foreground
private val choosePhoto: ChoosePhoto = ChoosePhoto(activity = this)
@ExperimentalPagerApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NavBody { nav, scaffoldState ->
NavHost(navController = nav, startDestination = MainMenu.Main.name) {
composable(MainMenu.Main.name) {
Main(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.List.name) {
AssociationList(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
composable(MainMenu.Center.name) {
val refresh: RefreshViewModel = viewModel()
refresh.refresh()
val load by refresh.refresh.observeAsState()
load?.let {
Center(navController = nav)
ShowSnackbar(scaffoldState = scaffoldState)
}
}
}
}
}
}
/**
* 个人中心
*
*/
@Composable
private fun Center(
model: CenterViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel(),
accountViewModel: AccountViewModel = viewModel(),
navController: NavHostController
) {
MainColumnFrame(
background = { Background(image = BackgroundImage.Center, alpha = 0.5F) },
mainMenu = MainMenu.Center,
nav = navController
) {
val photoLauncher = choosePhoto.photoLauncher()
val permissionLauncher = choosePhoto.permissionLauncher(photoLauncher = photoLauncher)
val personInfoData by TokenManager.getPersonInfoData().observeAsState()
personInfoData?.let {
Profile(
modifier = Modifier
.weight(0.4F)
.padding(10.dp),
setHeadImg = {
choosePhoto.requestPhoto(
photoLauncher = photoLauncher,
permissionLauncher = permissionLauncher
)
},
personInfoVo = it
)
}
Column(
modifier = Modifier.weight(0.6F),
verticalArrangement = Arrangement.SpaceEvenly
) {
TokenManager.getUserInfo()?.associationVo?.associationId?.let {
CenterMenuItem(text = model.myAssociationDesc) {
startActivity(
Intent(
this@MainActivity,
AssociationActivity::class.java
).apply {
putExtra(AssociationActivity::class.java.name, it)
})
}
CenterMenuItem(text = model.myLikeActivity) {
startActivity(
Intent(
this@MainActivity,
TendencyActivity::class.java
).apply {
putExtra(TendencyType::class.java.name, TendencyType.Like)
})
}
CenterMenuItem(text = model.myCollectActivity) {
startActivity(
Intent(
this@MainActivity,
TendencyActivity::class.java
).apply {
putExtra(TendencyType::class.java.name, TendencyType.Collect)
})
}
}
CenterMenuItem(text = "退出登录") {
accountViewModel.logout(this@MainActivity) {
scaffoldModel.update(message = it)
}
}
}
}
}
@Composable
private fun CenterMenuItem(text: String, onClick: () -> Unit = {}) {
Card(backgroundColor = MaterialTheme.colors.background) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier)
Row {
Text(text = text)
}
Row {
Icon(
painter = painterResource(id = R.drawable.ic_arrow_right),
contentDescription = null,
modifier = Modifier.size(50.dp)
)
}
}
}
}
/**
* 主界面
*/
@ExperimentalPagerApi
@Composable
private fun Main(navController: NavHostController) {
MainColumnFrame(
background = { Background(image = BackgroundImage.Main) },
mainMenu = MainMenu.Main,
nav = navController
) {
val viewModel: ImageViewModel = viewModel()
val imageList by viewModel.imageList.observeAsState()
imageList?.let {
val pagerState = rememberPagerState(pageCount = it.size)
Column(modifier = Modifier.weight(0.33F)) {
Notification()
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 15.dp),
verticalArrangement = Arrangement.SpaceEvenly
) {
MessageBoard()
ClubActivitiesTitle(vo = it[pagerState.currentPage])
}
}
Column(modifier = Modifier.weight(0.66F)) {
PosterWithDesc(pagerState = pagerState, imgList = it)
}
}
}
}
/**
* 社团列表
*
* @param navController
*/
@Composable
private fun AssociationList(navController: NavHostController) {
MainColumnFrame(
background = { Background(image = BackgroundImage.AssociationList) },
mainMenu = MainMenu.List,
nav = navController
) {
val associationVo = TokenManager.getUserInfo()?.associationVo
if (associationVo == null) {
RegisterAssociation(navController = navController)
}
AssociationSearch()
AssociationListBody()
}
}
/**
* 注册社团按钮
*
*/
@Composable
private fun RegisterAssociation(
navController: NavHostController
) {
val launch =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { it ->
when (it.resultCode) {
RESULT_OK -> {
it.data?.getStringExtra(RegAssociationActivity::class.java.name)?.let {
if (it == CheckStatus.Finish.name) {
navController.navigate(MainMenu.List.name)
}
}
}
}
}
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
) {
IconButton(onClick = {
launch.launch(Intent(this@MainActivity, RegAssociationActivity::class.java))
}) {
Icon(
painter = painterResource(id = R.drawable.ic_add_fill),
contentDescription = null,
modifier = Modifier.size(50.dp),
)
}
}
}
/**
* 社团列表
*
*/
@Composable
private fun AssociationListBody(
model: AssociationListViewModel = viewModel()
) {
val associationListList: MutableList<AssociationVo>? by model.data.observeAsState()
val listState = rememberLazyListState()
LazyColumn(state = listState) {
associationListList?.chunked(2)?.forEach {
item {
Row {
Spacer(modifier = Modifier.weight(0.1F))
Box(modifier = Modifier.weight(0.35F)) {
Association(associationVo = it[0])
}
Spacer(modifier = Modifier.weight(0.05F))
if (it.size == 2) {
Box(modifier = Modifier.weight(0.35F)) {
Association(associationVo = it[1])
}
} else {
Box(
modifier = Modifier
.weight(0.35F)
.border(width = 1.dp, color = MaterialTheme.colors.onBackground)
)
}
Spacer(modifier = Modifier.weight(0.1F))
}
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(10.dp)
)
}
}
}
if (listState.layoutInfo.totalItemsCount - listState.firstVisibleItemIndex == model.initSize / 2 - 1) {
TODO("加载更多")
}
}
/**
* 社团卡片
*
* @param associationVo
*/
@Composable
private fun Association(associationVo: AssociationVo) {
Card(modifier = Modifier.clickable(onClick = {
val intent = Intent(this, AssociationActivity::class.java)
intent.putExtra(AssociationActivity::class.java.name, associationVo.associationId)
startActivity(intent)
})) {
val backgroundImage = rememberCoilPainter(request = R.drawable.association_list_border)
Image(
painter = backgroundImage,
contentDescription = null
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
Text(text = associationVo.name)
}
}
}
/**
* 社团检索
*
*/
@Composable
private fun AssociationSearch(
model: AssociationListViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
Card(modifier = Modifier.padding(horizontal = 50.dp, vertical = 10.dp)) {
Column {
BaseTextField(
form = model.name,
singeLine = true,
modifier = Modifier.padding(horizontal = 10.dp)
)
BaseTextField(
form = model.desc,
singeLine = true,
modifier = Modifier.padding(horizontal = 10.dp)
)
Spacer(
modifier = Modifier.height(10.dp)
)
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
OutlinedButton(
onClick = {
model.load {
scaffoldModel.update(message = it)
}
},
modifier = Modifier.width(100.dp)
) {
Text(text = stringResource(id = R.string.search_btn))
}
}
Spacer(
modifier = Modifier.height(10.dp)
)
}
}
}
/**
* 通知
*
*/
@Composable
private fun Notification(notificationViewModel: NotificationViewModel = viewModel()) {
val count by notificationViewModel.count.observeAsState(null)
count?.let {
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
) {
IconButton(onClick = {
startActivity(Intent(this@MainActivity, SysMessageActivity::class.java))
}) {
Icon(
painter = painterResource(id = if (it > 0) R.drawable.ic_notice else R.drawable.ic_notification),
contentDescription = null
)
}
}
}
}
/**
* 留言板
*
*/
@Composable
private fun MessageBoard(
modifier: Modifier = Modifier,
model: MarqueeViewModel = viewModel(),
scaffoldModel: ScaffoldModel = viewModel()
) {
model.loadMessage {
scaffoldModel.update(message = it)
}
Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = { model.openDialog() }) {
Icon(
painter = painterResource(id = R.drawable.ic_comments),
contentDescription = null,
)
}
SendComment(model = model)
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
) {
Marquee(model = model)
}
}
}
}
/**
* 活动标题
*
*/
@ExperimentalPagerApi
@Composable
private fun ClubActivitiesTitle(modifier: Modifier = Modifier, vo: MainActivityPhotoVo) {
Card(modifier = modifier, backgroundColor = MaterialTheme.colors.background) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = vo.activityVo.activityName,
style = MaterialTheme.typography.h6,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
}
}
/**
* 带介绍活动海报
*
*/
@ExperimentalPagerApi
@Composable
private fun PosterWithDesc(
pagerState: PagerState,
imgList: List<MainActivityPhotoVo>
) {
imgList.let {
HorizontalPager(state = pagerState) { page ->
// Our page content
Logger.i("page=${page}")
Column {
val photo = rememberCoilPainter(request = Api.buildUrl(it[page].url))
Poster(
modifier = Modifier
.weight(0.6F)
.fillMaxWidth()
) {
when (photo.loadState) {
is ImageLoadState.Loading -> CircularProgressIndicator()
is ImageLoadState.Success -> it[page].apply {
Image(
painter = photo,
contentDescription = activityVo.activityName,
modifier = Modifier.clickable(onClick = {
startActivity(
Intent(
this@MainActivity,
ActivityDetailActivity::class.java
).apply {
putExtra(
ActivityDetailActivity::class.java.name,
activityVo.activityId
)
putExtra(
AssociationActivity::class.java.name,
associationVo.associationId
)
})
})
)
}
else -> Text(text = "图片加载失败")
}
}
DescCard(
modifier = Modifier
.weight(0.4F)
.fillMaxWidth(),
content = it[page].activityVo.activityDesc
)
}
}
}
}
}