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? 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 ) { 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 ) } } } } }