调整部分 UI
This commit is contained in:
@@ -19,8 +19,8 @@ import coil.request.ImageRequest
|
|||||||
import com.aiosman.riderpro.utils.BlurHashDecoder
|
import com.aiosman.riderpro.utils.BlurHashDecoder
|
||||||
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
||||||
|
|
||||||
private const val DEFAULT_HASHED_BITMAP_WIDTH = 4
|
const val DEFAULT_HASHED_BITMAP_WIDTH = 4
|
||||||
private const val DEFAULT_HASHED_BITMAP_HEIGHT = 3
|
const val DEFAULT_HASHED_BITMAP_HEIGHT = 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used to load an image asynchronously and blur it using BlurHash.
|
* This function is used to load an image asynchronously and blur it using BlurHash.
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import coil.request.SuccessResult
|
import coil.request.SuccessResult
|
||||||
|
import com.aiosman.riderpro.utils.BlurHashDecoder
|
||||||
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -40,18 +42,53 @@ fun rememberImageBitmap(imageUrl: String, imageLoader: ImageLoader): Bitmap? {
|
|||||||
|
|
||||||
return bitmap
|
return bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomAsyncImage(
|
fun CustomAsyncImage(
|
||||||
context: Context,
|
context: Context,
|
||||||
imageUrl: String,
|
imageUrl: String,
|
||||||
contentDescription: String?,
|
contentDescription: String?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
blurHash: String? = null,
|
||||||
contentScale: ContentScale = ContentScale.Crop
|
contentScale: ContentScale = ContentScale.Crop
|
||||||
) {
|
) {
|
||||||
val bitmap = rememberImageBitmap(imageUrl, getImageLoader(context))
|
|
||||||
val imageLoader = getImageLoader(context)
|
val imageLoader = getImageLoader(context)
|
||||||
|
val blurBitmap = remember(blurHash) {
|
||||||
|
blurHash?.let {
|
||||||
|
BlurHashDecoder.decode(
|
||||||
|
blurHash = it,
|
||||||
|
width = DEFAULT_HASHED_BITMAP_WIDTH,
|
||||||
|
height = DEFAULT_HASHED_BITMAP_HEIGHT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var bitmap by remember(imageUrl) { mutableStateOf<Bitmap?>(null) }
|
||||||
|
|
||||||
|
LaunchedEffect(imageUrl) {
|
||||||
|
if (bitmap == null) {
|
||||||
|
val request = ImageRequest.Builder(context)
|
||||||
|
.data(imageUrl)
|
||||||
|
.crossfade(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val result = withContext(Dispatchers.IO) {
|
||||||
|
(imageLoader.execute(request) as? SuccessResult)?.drawable?.toBitmap()
|
||||||
|
}
|
||||||
|
bitmap = result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = bitmap,
|
model = bitmap ?: ImageRequest.Builder(context)
|
||||||
|
.data(imageUrl)
|
||||||
|
.crossfade(true)
|
||||||
|
.apply {
|
||||||
|
if (blurBitmap != null) {
|
||||||
|
placeholder(blurBitmap.toDrawable(context.resources))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build(),
|
||||||
contentDescription = contentDescription,
|
contentDescription = contentDescription,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
contentScale = contentScale,
|
contentScale = contentScale,
|
||||||
|
|||||||
@@ -57,12 +57,15 @@ fun FavouriteScreen() {
|
|||||||
.weight(1f)
|
.weight(1f)
|
||||||
.background(color = Color(0xFFFFFFFF))
|
.background(color = Color(0xFFFFFFFF))
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp)
|
||||||
) {
|
) {
|
||||||
NoticeScreenHeader(
|
NoticeScreenHeader(
|
||||||
"FAVOURITE",
|
"FAVOURITE",
|
||||||
moreIcon = false
|
moreIcon = false
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(28.dp))
|
}
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
state = listState,
|
state = listState,
|
||||||
|
|||||||
@@ -45,8 +45,12 @@ fun FollowerScreen() {
|
|||||||
val model = FollowerViewModel
|
val model = FollowerViewModel
|
||||||
var dataFlow = model.followerItemsFlow
|
var dataFlow = model.followerItemsFlow
|
||||||
var followers = dataFlow.collectAsLazyPagingItems()
|
var followers = dataFlow.collectAsLazyPagingItems()
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp)
|
||||||
|
) {
|
||||||
NoticeScreenHeader("FOLLOWERS")
|
NoticeScreenHeader("FOLLOWERS")
|
||||||
Spacer(modifier = Modifier.height(28.dp))
|
|
||||||
|
}
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
model.updateNotice()
|
model.updateNotice()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.aiosman.riderpro.LocalNavController
|
||||||
|
import com.aiosman.riderpro.ui.NavigationRoute
|
||||||
import com.aiosman.riderpro.ui.index.tabs.add.AddPage
|
import com.aiosman.riderpro.ui.index.tabs.add.AddPage
|
||||||
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
|
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
|
||||||
import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList
|
import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList
|
||||||
@@ -41,6 +43,7 @@ fun IndexScreen() {
|
|||||||
val navigationBarHeight = with(LocalDensity.current) {
|
val navigationBarHeight = with(LocalDensity.current) {
|
||||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||||
}
|
}
|
||||||
|
val navController = LocalNavController.current
|
||||||
val item = listOf(
|
val item = listOf(
|
||||||
NavigationItem.Home,
|
NavigationItem.Home,
|
||||||
NavigationItem.Search,
|
NavigationItem.Search,
|
||||||
@@ -70,6 +73,10 @@ fun IndexScreen() {
|
|||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
onClick = {
|
onClick = {
|
||||||
|
if (it.route === NavigationItem.Add.route) {
|
||||||
|
navController.navigate(NavigationRoute.NewPost.route)
|
||||||
|
return@NavigationBarItem
|
||||||
|
}
|
||||||
model.tabIndex = idx
|
model.tabIndex = idx
|
||||||
},
|
},
|
||||||
colors = NavigationBarItemColors(
|
colors = NavigationBarItemColors(
|
||||||
|
|||||||
@@ -371,6 +371,7 @@ fun PostImageView(
|
|||||||
context,
|
context,
|
||||||
image.thumbnail,
|
image.thumbnail,
|
||||||
contentDescription = "Image",
|
contentDescription = "Image",
|
||||||
|
blurHash = image.blurHash,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.sharedElement(
|
.sharedElement(
|
||||||
|
|||||||
@@ -56,12 +56,19 @@ fun LikeScreen() {
|
|||||||
.weight(1f)
|
.weight(1f)
|
||||||
.background(color = Color(0xFFFFFFFF))
|
.background(color = Color(0xFFFFFFFF))
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 16.dp)
|
||||||
) {
|
) {
|
||||||
NoticeScreenHeader(
|
NoticeScreenHeader(
|
||||||
"LIKES",
|
"LIKES",
|
||||||
moreIcon = false
|
moreIcon = false
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(28.dp))
|
}
|
||||||
|
|
||||||
|
// Spacer(modifier = Modifier.height(28.dp))
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
state = listState,
|
state = listState,
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ fun SignupScreen() {
|
|||||||
fun googleLogin() {
|
fun googleLogin() {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
GoogleLogin(context) {
|
GoogleLogin(context) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ fun UserAuthScreen() {
|
|||||||
}
|
}
|
||||||
} catch (e: ServiceException) {
|
} catch (e: ServiceException) {
|
||||||
// handle error
|
// handle error
|
||||||
|
e.printStackTrace()
|
||||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ fun NewPostScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddImageGrid()
|
AddImageGrid()
|
||||||
AdditionalPostItem()
|
// AdditionalPostItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,18 +173,14 @@ fun AddImageGrid() {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val model = NewPostViewModel
|
val model = NewPostViewModel
|
||||||
|
|
||||||
val pickImageLauncher = rememberLauncherForActivityResult(
|
val pickImagesLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.StartActivityForResult()
|
contract = ActivityResultContracts.GetMultipleContents()
|
||||||
) { result ->
|
) { uris ->
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
if (uris.isNotEmpty()) {
|
||||||
val uri = result.data?.data
|
model.imageUriList += uris.map { it.toString() }
|
||||||
if (uri != null) {
|
}
|
||||||
model.imageUriList += uri.toString()
|
|
||||||
// get filename and extension
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val stroke = Stroke(
|
val stroke = Stroke(
|
||||||
width = 2f,
|
width = 2f,
|
||||||
pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
|
pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
|
||||||
@@ -206,7 +202,7 @@ fun AddImageGrid() {
|
|||||||
contentDescription = "Image",
|
contentDescription = "Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(110.dp)
|
.size(110.dp)
|
||||||
.background(Color(0xFFFFFFFF))
|
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
drawRoundRect(color = Color(0xFF999999), style = stroke)
|
drawRoundRect(color = Color(0xFF999999), style = stroke)
|
||||||
},
|
},
|
||||||
@@ -216,18 +212,12 @@ fun AddImageGrid() {
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(110.dp)
|
.size(110.dp)
|
||||||
.background(Color(0xFFFFFFFF))
|
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
drawRoundRect(color = Color(0xFF999999), style = stroke)
|
drawRoundRect(color = Color(0xFF999999), style = stroke)
|
||||||
}
|
}
|
||||||
.clickable(
|
.noRippleClickable{
|
||||||
indication = null,
|
pickImagesLauncher.launch("image/*")
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
|
||||||
) {
|
|
||||||
Intent(Intent.ACTION_PICK).apply {
|
|
||||||
type = "image/*"
|
|
||||||
pickImageLauncher.launch(this)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ object Utils {
|
|||||||
.directory(context.cacheDir.resolve("image_cache"))
|
.directory(context.cacheDir.resolve("image_cache"))
|
||||||
.maxSizePercent(0.02) // 设置磁盘缓存大小为可用存储空间的 2%
|
.maxSizePercent(0.02) // 设置磁盘缓存大小为可用存储空间的 2%
|
||||||
.build()
|
.build()
|
||||||
}.build()
|
}
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTimeAgo(date: Date): String {
|
fun getTimeAgo(date: Date): String {
|
||||||
|
|||||||
Reference in New Issue
Block a user