From 21825a10e1b11a77d94b2aa450eb0c803fb12095 Mon Sep 17 00:00:00 2001 From: HuanCheng65 <22636177+HuanCheng65@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:53:30 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BC=98=E5=8C=96=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../editprofile/view/EditProfileActivity.kt | 4 +- .../tieba/post/ui/page/main/home/HomePage.kt | 60 ++++++++++--------- .../tieba/post/ui/page/main/user/UserPage.kt | 43 +++++++++---- .../tieba/post/ui/widgets/Chip.kt | 41 +++++++++++++ .../tieba/post/ui/widgets/compose/Avatars.kt | 59 +++++++++++++----- .../tieba/post/ui/widgets/compose/Toolbar.kt | 26 ++++---- .../tieba/post/utils/AccountUtil.kt | 15 +++-- .../tieba/post/utils/EmoticonManager.kt | 12 +++- 8 files changed, 177 insertions(+), 83 deletions(-) create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/Chip.kt diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt index 5e1b8de5..3fac1b5f 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt @@ -34,10 +34,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import androidx.lifecycle.lifecycleScope -import coil.compose.AsyncImage import com.bumptech.glide.Glide import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition +import com.github.panpf.sketch.compose.AsyncImage import com.google.accompanist.placeholder.material.placeholder import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.huanchengfly.tieba.post.R @@ -266,7 +266,7 @@ fun EditProfileCard( .placeholder(visible = loading) ) { AsyncImage( - model = StringUtil.getAvatarUrl(portrait), + imageUri = StringUtil.getAvatarUrl(portrait), contentDescription = null, modifier = Modifier.fillMaxSize() ) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/home/HomePage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/home/HomePage.kt index 9a1c7dbe..00ff50d7 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/home/HomePage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/home/HomePage.kt @@ -26,7 +26,6 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.material.Text @@ -43,7 +42,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment.Companion.Center import androidx.compose.ui.Alignment.Companion.CenterVertically -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color @@ -55,9 +53,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import coil.compose.AsyncImage -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest +import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.google.accompanist.placeholder.placeholder import com.google.accompanist.swiperefresh.SwipeRefresh import com.google.accompanist.swiperefresh.rememberSwipeRefreshState @@ -70,6 +66,7 @@ import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.getInt import com.huanchengfly.tieba.post.goToActivity import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme +import com.huanchengfly.tieba.post.ui.widgets.Chip import com.huanchengfly.tieba.post.ui.widgets.compose.AccountNavIconIfCompact import com.huanchengfly.tieba.post.ui.widgets.compose.ActionItem import com.huanchengfly.tieba.post.ui.widgets.compose.ConfirmDialog @@ -155,18 +152,7 @@ private fun Header( invert: Boolean = false, modifier: Modifier = Modifier ) { - Text( - color = if (invert) MaterialTheme.colors.onSecondary else ExtendedTheme.colors.onChip, - fontSize = 12.sp, - fontWeight = FontWeight.Bold, - text = text, - modifier = Modifier - .padding(start = 16.dp) - .clip(RoundedCornerShape(100)) - .then(modifier) - .background(color = if (invert) MaterialTheme.colors.secondary else ExtendedTheme.colors.chip) - .padding(horizontal = 16.dp, vertical = 4.dp) - ) + Chip(text = text, invertColor = invert, modifier = modifier) } @Composable @@ -179,8 +165,13 @@ private fun ForumItemPlaceholder( .padding(horizontal = 16.dp, vertical = 12.dp) ) { if (showAvatar) { - AsyncImage( - model = ImageUtil.getPlaceHolder(LocalContext.current, 0), + Image( + painter = rememberDrawablePainter( + drawable = ImageUtil.getPlaceHolder( + LocalContext.current, + 0 + ) + ), contentDescription = null, modifier = Modifier .clip(CircleShape) @@ -224,7 +215,6 @@ private fun ForumItemPlaceholder( } } -@OptIn(ExperimentalComposeUiApi::class) @Composable private fun ForumItem( viewModel: HomeViewModel, @@ -317,19 +307,30 @@ private fun ForumItem( ) { AnimatedVisibility(visible = showAvatar) { Row { - Image( - painter = rememberAsyncImagePainter( - ImageRequest.Builder(LocalContext.current).data(item.avatar).apply { - placeholder(ImageUtil.getPlaceHolder(LocalContext.current, 0)) - crossfade(true) - }.build() - ), + coil.compose.AsyncImage( + model = item.avatar, contentDescription = null, modifier = Modifier .clip(CircleShape) .size(40.dp) .align(CenterVertically), ) +// AsyncImage( +// imageUri = item.avatar, +// contentDescription = null, +// modifier = Modifier +// .clip(CircleShape) +// .size(40.dp) +// .align(CenterVertically), +// ) { +// resultCachePolicy(CachePolicy.DISABLED) +// memoryCachePolicy(CachePolicy.DISABLED) +// disallowReuseBitmap() +// } +// { +// placeholder(ImageUtil.getPlaceHolder(context, 0)) +// crossfade() +// } Spacer(modifier = Modifier.width(14.dp)) } } @@ -404,7 +405,7 @@ fun HomePage( initial = emptyList() ) var listSingle by remember { mutableStateOf(context.appPreferences.listSingle) } - val gridCells by derivedStateOf { getGridCells(context, listSingle) } + val gridCells by remember { derivedStateOf { getGridCells(context, listSingle) } } Scaffold( backgroundColor = Color.Transparent, topBar = { @@ -429,10 +430,11 @@ fun HomePage( ) }, modifier = Modifier.fillMaxSize(), - ) { + ) { contentPaddings -> SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing = isLoading), onRefresh = { viewModel.send(HomeUiIntent.Refresh) }, + modifier = Modifier.padding(contentPaddings) ) { val gridState = rememberLazyGridState() LazyVerticalGrid( diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/user/UserPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/user/UserPage.kt index 4bf00a7d..fa87fe63 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/user/UserPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/user/UserPage.kt @@ -4,7 +4,18 @@ import android.graphics.Typeface import androidx.compose.animation.core.animateIntAsState import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape @@ -34,7 +45,11 @@ import com.google.accompanist.placeholder.placeholder import com.google.accompanist.swiperefresh.SwipeRefresh import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import com.huanchengfly.tieba.post.R -import com.huanchengfly.tieba.post.activities.* +import com.huanchengfly.tieba.post.activities.AppThemeActivity +import com.huanchengfly.tieba.post.activities.HistoryActivity +import com.huanchengfly.tieba.post.activities.UserActivity +import com.huanchengfly.tieba.post.activities.UserCollectActivity +import com.huanchengfly.tieba.post.activities.WebViewActivity import com.huanchengfly.tieba.post.arch.collectPartialAsState import com.huanchengfly.tieba.post.arch.pageViewModel import com.huanchengfly.tieba.post.goToActivity @@ -151,14 +166,16 @@ private fun InfoCard( ) } Spacer(modifier = Modifier.width(16.dp)) - Avatar( - data = avatar, - size = Sizes.Large, - contentDescription = stringResource(id = R.string.desc_user_avatar), - modifier = Modifier - .align(Alignment.Bottom) - .placeholder(visible = isPlaceholder, color = ExtendedTheme.colors.chip), - ) + if (avatar != null) { + Avatar( + data = avatar, + size = Sizes.Large, + contentDescription = stringResource(id = R.string.desc_user_avatar), + modifier = Modifier + .align(Alignment.Bottom) + .placeholder(visible = isPlaceholder, color = ExtendedTheme.colors.chip), + ) + } } } @@ -240,11 +257,13 @@ fun UserPage( modifier = Modifier .statusBarsPadding() .fillMaxSize() - ) { + ) { contentPaddings -> SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing = isLoading), onRefresh = { viewModel.send(UserUiIntent.Refresh) }, - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(contentPaddings), ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/Chip.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/Chip.kt new file mode 100644 index 00000000..128cad17 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/Chip.kt @@ -0,0 +1,41 @@ +package com.huanchengfly.tieba.post.ui.widgets + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme +import com.huanchengfly.tieba.post.utils.ThemeUtil + +@Composable +fun Chip( + text: String, + invertColor: Boolean, + modifier: Modifier +) { + Text( + color = if (invertColor) + if (ThemeUtil.isNightMode()) MaterialTheme.colors.secondary else MaterialTheme.colors.onSecondary + else ExtendedTheme.colors.onChip, + fontSize = 12.sp, + fontWeight = FontWeight.Bold, + text = text, + modifier = Modifier + .padding(start = 16.dp) + .clip(RoundedCornerShape(100)) + .then(modifier) + .background( + color = if (invertColor) + if (ThemeUtil.isNightMode()) MaterialTheme.colors.secondary.copy(alpha = 0.3f) else MaterialTheme.colors.secondary + else ExtendedTheme.colors.chip + ) + .padding(horizontal = 16.dp, vertical = 4.dp) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Avatars.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Avatars.kt index fa48c05d..151708d8 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Avatars.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Avatars.kt @@ -1,5 +1,6 @@ package com.huanchengfly.tieba.post.ui.widgets.compose +import android.graphics.drawable.Drawable import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.padding @@ -14,16 +15,17 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest +import com.github.panpf.sketch.compose.AsyncImage +import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.huanchengfly.tieba.post.utils.ImageUtil object Sizes { val Small = 36.dp - val Middle = 48.dp + val Medium = 48.dp val Large = 56.dp } @@ -57,17 +59,42 @@ fun Avatar( contentDescription: String?, modifier: Modifier = Modifier, ) { - Image( - painter = rememberAsyncImagePainter( - ImageRequest.Builder(LocalContext.current) - .data(data) - .apply { - placeholder(ImageUtil.getPlaceHolder(LocalContext.current, 0)) - crossfade(true) - } - .build() - ), - contentDescription = contentDescription, - modifier = modifier.size(size).clip(CircleShape), - ) + val context = LocalContext.current + when (data) { + is Int -> { + Image( + painter = rememberDrawablePainter(drawable = context.getDrawable(data)), + contentDescription = contentDescription, + modifier = modifier + .size(size) + .clip(CircleShape), + ) + } + + is Drawable -> { + Image( + painter = rememberDrawablePainter(drawable = data), + contentDescription = contentDescription, + modifier = modifier + .size(size) + .clip(CircleShape), + ) + } + + is String? -> { + AsyncImage( + imageUri = data, + contentDescription = contentDescription, + modifier = modifier + .size(size) + .clip(CircleShape), + contentScale = ContentScale.Crop + ) { + placeholder(ImageUtil.getPlaceHolder(context, 0)) + crossfade() + } + } + + else -> throw IllegalArgumentException("不支持该类型") + } } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Toolbar.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Toolbar.kt index 861b861d..ae273630 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Toolbar.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Toolbar.kt @@ -42,9 +42,8 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import coil.compose.AsyncImage -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest +import com.github.panpf.sketch.compose.AsyncImage +import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.activities.LoginActivity import com.huanchengfly.tieba.post.arch.BaseComposeActivity.Companion.LocalWindowSizeClass @@ -71,8 +70,8 @@ fun AccountNavIcon( val currentAccount = LocalAccount.current if (spacer) Spacer(modifier = Modifier.width(12.dp)) if (currentAccount == null) { - AsyncImage( - model = R.drawable.ic_launcher_new_round, + Image( + painter = rememberDrawablePainter(drawable = LocalContext.current.getDrawable(R.drawable.ic_launcher_new_round)), contentDescription = null, modifier = Modifier .clip(CircleShape) @@ -137,21 +136,16 @@ fun AccountNavIcon( onClick = onClick, shape = CircleShape ) { - Image( - painter = rememberAsyncImagePainter( - ImageRequest.Builder(LocalContext.current) - .data(StringUtil.getAvatarUrl(currentAccount.portrait)) - .apply { - placeholder(ImageUtil.getPlaceHolder(LocalContext.current, 0)) - crossfade(true) - } - .build() - ), + AsyncImage( + imageUri = StringUtil.getAvatarUrl(currentAccount.portrait), contentDescription = stringResource(id = R.string.title_switch_account_long_press), modifier = Modifier .clip(CircleShape) .size(size), - ) + ) { + placeholder(ImageUtil.getPlaceHolder(context, 0)) + crossfade() + } } } } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/AccountUtil.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/AccountUtil.kt index 083a5c13..54b8da21 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/AccountUtil.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/AccountUtil.kt @@ -4,7 +4,12 @@ import android.content.Context import android.content.Intent import android.webkit.CookieManager import android.widget.Toast -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.staticCompositionLocalOf import com.huanchengfly.tieba.post.App import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.api.TiebaApi @@ -161,11 +166,11 @@ object AccountUtil { @JvmStatic fun updateLoginInfo(cookie: String): Boolean { - val bdussSplit = cookie.split("BDUSS=").toTypedArray() - val sTokenSplit = cookie.split("STOKEN=").toTypedArray() + val bdussSplit = cookie.split("BDUSS=") + val sTokenSplit = cookie.split("STOKEN=") if (bdussSplit.size > 1 && sTokenSplit.size > 1) { - val bduss = bdussSplit[1].split(";").toTypedArray()[0] - val sToken = sTokenSplit[1].split(";").toTypedArray()[0] + val bduss = bdussSplit[1].split(";")[0] + val sToken = sTokenSplit[1].split(";")[0] val account = getAccountInfoByBduss(bduss) if (account != null) { account.apply { diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/EmoticonManager.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/EmoticonManager.kt index 80d165ab..bfa15e63 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/EmoticonManager.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/EmoticonManager.kt @@ -5,6 +5,7 @@ import android.graphics.Bitmap import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import androidx.appcompat.content.res.AppCompatResources +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.size import androidx.compose.foundation.text.InlineTextContent import androidx.compose.material.LocalTextStyle @@ -14,8 +15,8 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.* import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import coil.compose.AsyncImage import com.bumptech.glide.Glide +import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.huanchengfly.tieba.post.App import com.huanchengfly.tieba.post.models.EmoticonCache import com.huanchengfly.tieba.post.pxToDp @@ -107,8 +108,13 @@ object EmoticonManager { "Emoticon#$id" to InlineTextContent( placeholder = Placeholder(heightPx.pxToSp().sp, heightPx.pxToSp().sp, PlaceholderVerticalAlign.TextCenter), children = { - AsyncImage( - model = getEmoticonDrawable(LocalContext.current, id), + Image( + painter = rememberDrawablePainter( + drawable = getEmoticonDrawable( + LocalContext.current, + id + ) + ), contentDescription = null, modifier = Modifier.size(heightPx.pxToDp().dp) )