diff --git a/app/src/main/java/com/aiosman/riderpro/ui/composables/BlurHash.kt b/app/src/main/java/com/aiosman/riderpro/ui/composables/BlurHash.kt index 70a01b2..5400939 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/composables/BlurHash.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/composables/BlurHash.kt @@ -19,8 +19,8 @@ import coil.request.ImageRequest import com.aiosman.riderpro.utils.BlurHashDecoder import com.aiosman.riderpro.utils.Utils.getImageLoader -private const val DEFAULT_HASHED_BITMAP_WIDTH = 4 -private const val DEFAULT_HASHED_BITMAP_HEIGHT = 3 +const val DEFAULT_HASHED_BITMAP_WIDTH = 4 +const val DEFAULT_HASHED_BITMAP_HEIGHT = 3 /** * This function is used to load an image asynchronously and blur it using BlurHash. diff --git a/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt b/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt index a861c46..4963212 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt @@ -12,10 +12,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.core.graphics.drawable.toBitmap +import androidx.core.graphics.drawable.toDrawable import coil.ImageLoader import coil.compose.AsyncImage import coil.request.ImageRequest import coil.request.SuccessResult +import com.aiosman.riderpro.utils.BlurHashDecoder import com.aiosman.riderpro.utils.Utils.getImageLoader import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -40,18 +42,53 @@ fun rememberImageBitmap(imageUrl: String, imageLoader: ImageLoader): Bitmap? { return bitmap } + @Composable fun CustomAsyncImage( context: Context, imageUrl: String, contentDescription: String?, modifier: Modifier = Modifier, + blurHash: String? = null, contentScale: ContentScale = ContentScale.Crop ) { - val bitmap = rememberImageBitmap(imageUrl, 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(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( - model = bitmap, + model = bitmap ?: ImageRequest.Builder(context) + .data(imageUrl) + .crossfade(true) + .apply { + if (blurBitmap != null) { + placeholder(blurBitmap.toDrawable(context.resources)) + } + } + .build(), contentDescription = contentDescription, modifier = modifier, contentScale = contentScale, diff --git a/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteScreen.kt b/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteScreen.kt index bc15a0a..9c5985c 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteScreen.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteScreen.kt @@ -58,11 +58,14 @@ fun FavouriteScreen() { .background(color = Color(0xFFFFFFFF)) .padding(horizontal = 16.dp) ) { - NoticeScreenHeader( - "FAVOURITE", - moreIcon = false - ) - Spacer(modifier = Modifier.height(28.dp)) + Box( + modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp) + ) { + NoticeScreenHeader( + "FAVOURITE", + moreIcon = false + ) + } LazyColumn( modifier = Modifier.weight(1f), state = listState, diff --git a/app/src/main/java/com/aiosman/riderpro/ui/follower/FollowerPage.kt b/app/src/main/java/com/aiosman/riderpro/ui/follower/FollowerPage.kt index b60f72e..ef17eb0 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/follower/FollowerPage.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/follower/FollowerPage.kt @@ -45,8 +45,12 @@ fun FollowerScreen() { val model = FollowerViewModel var dataFlow = model.followerItemsFlow var followers = dataFlow.collectAsLazyPagingItems() - NoticeScreenHeader("FOLLOWERS") - Spacer(modifier = Modifier.height(28.dp)) + Box( + modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp) + ) { + NoticeScreenHeader("FOLLOWERS") + + } LaunchedEffect(Unit) { model.updateNotice() } diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt index 805854b..721c078 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/Index.kt @@ -25,6 +25,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity 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.message.NotificationsScreen import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList @@ -41,6 +43,7 @@ fun IndexScreen() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } + val navController = LocalNavController.current val item = listOf( NavigationItem.Home, NavigationItem.Search, @@ -70,6 +73,10 @@ fun IndexScreen() { NavigationBarItem( selected = isSelected, onClick = { + if (it.route === NavigationItem.Add.route) { + navController.navigate(NavigationRoute.NewPost.route) + return@NavigationBarItem + } model.tabIndex = idx }, colors = NavigationBarItemColors( diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/moment/Moment.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/moment/Moment.kt index b62742f..e7281e3 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/moment/Moment.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/moment/Moment.kt @@ -371,6 +371,7 @@ fun PostImageView( context, image.thumbnail, contentDescription = "Image", + blurHash = image.blurHash, contentScale = ContentScale.Crop, modifier = Modifier .sharedElement( diff --git a/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt b/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt index 62d69b0..741cece 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt @@ -57,11 +57,18 @@ fun LikeScreen() { .background(color = Color(0xFFFFFFFF)) .padding(horizontal = 16.dp) ) { - NoticeScreenHeader( - "LIKES", - moreIcon = false - ) - Spacer(modifier = Modifier.height(28.dp)) + Box( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + ) { + NoticeScreenHeader( + "LIKES", + moreIcon = false + ) + } + +// Spacer(modifier = Modifier.height(28.dp)) LazyColumn( modifier = Modifier.weight(1f), state = listState, diff --git a/app/src/main/java/com/aiosman/riderpro/ui/login/signup.kt b/app/src/main/java/com/aiosman/riderpro/ui/login/signup.kt index c6a2992..2efacb5 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/login/signup.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/login/signup.kt @@ -57,6 +57,7 @@ fun SignupScreen() { fun googleLogin() { coroutineScope.launch { try { + GoogleLogin(context) { coroutineScope.launch { try { diff --git a/app/src/main/java/com/aiosman/riderpro/ui/login/userauth.kt b/app/src/main/java/com/aiosman/riderpro/ui/login/userauth.kt index 6ae8c21..631ec04 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/login/userauth.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/login/userauth.kt @@ -135,6 +135,7 @@ fun UserAuthScreen() { } } catch (e: ServiceException) { // handle error + e.printStackTrace() Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/com/aiosman/riderpro/ui/post/NewPost.kt b/app/src/main/java/com/aiosman/riderpro/ui/post/NewPost.kt index a7ad4f8..0b0ea52 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/post/NewPost.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/post/NewPost.kt @@ -104,7 +104,7 @@ fun NewPostScreen() { } AddImageGrid() - AdditionalPostItem() +// AdditionalPostItem() } } } @@ -173,18 +173,14 @@ fun AddImageGrid() { val context = LocalContext.current val model = NewPostViewModel - val pickImageLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.StartActivityForResult() - ) { result -> - if (result.resultCode == Activity.RESULT_OK) { - val uri = result.data?.data - if (uri != null) { - model.imageUriList += uri.toString() - // get filename and extension - } - + val pickImagesLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.GetMultipleContents() + ) { uris -> + if (uris.isNotEmpty()) { + model.imageUriList += uris.map { it.toString() } } } + val stroke = Stroke( width = 2f, pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f) @@ -206,7 +202,7 @@ fun AddImageGrid() { contentDescription = "Image", modifier = Modifier .size(110.dp) - .background(Color(0xFFFFFFFF)) + .drawBehind { drawRoundRect(color = Color(0xFF999999), style = stroke) }, @@ -216,18 +212,12 @@ fun AddImageGrid() { Box( modifier = Modifier .size(110.dp) - .background(Color(0xFFFFFFFF)) + .drawBehind { drawRoundRect(color = Color(0xFF999999), style = stroke) } - .clickable( - indication = null, - interactionSource = remember { MutableInteractionSource() } - ) { - Intent(Intent.ACTION_PICK).apply { - type = "image/*" - pickImageLauncher.launch(this) - } + .noRippleClickable{ + pickImagesLauncher.launch("image/*") }, ) { Image( diff --git a/app/src/main/java/com/aiosman/riderpro/utils/Utils.kt b/app/src/main/java/com/aiosman/riderpro/utils/Utils.kt index 38899d8..a93f46f 100644 --- a/app/src/main/java/com/aiosman/riderpro/utils/Utils.kt +++ b/app/src/main/java/com/aiosman/riderpro/utils/Utils.kt @@ -31,7 +31,8 @@ object Utils { .directory(context.cacheDir.resolve("image_cache")) .maxSizePercent(0.02) // 设置磁盘缓存大小为可用存储空间的 2% .build() - }.build() + } + .build() } fun getTimeAgo(date: Date): String {