diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 520bb3c..d683e0a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,21 +1,22 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.compose.compiler) id("com.google.gms.google-services") id("com.google.firebase.crashlytics") id("com.google.firebase.firebase-perf") id("org.jetbrains.kotlin.kapt") - id("com.google.devtools.ksp") version "1.9.10-1.0.13" + alias(libs.plugins.ksp) } android { namespace = "com.aiosman.ravenow" - compileSdk = 34 + compileSdk = 35 defaultConfig { applicationId = "com.aiosman.ravenow" minSdk = 24 - targetSdk = 34 + targetSdk = 35 versionCode = 1000019 versionName = "1.0.000.19" @@ -46,19 +47,16 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } buildFeatures { compose = true buildConfig = true } - composeOptions { - kotlinCompilerExtensionVersion = "1.5.3" - } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" @@ -99,11 +97,13 @@ dependencies { debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) implementation(libs.androidx.animation) - implementation(libs.coil.compose) implementation(libs.coil) + implementation(libs.coil.compose) + implementation(libs.coil.network.okhttp) implementation(libs.play.services.auth) implementation(libs.kotlin.faker) implementation(libs.androidx.material) + implementation(libs.androidx.material.icons.extended) implementation(libs.zoomable) implementation(libs.retrofit) implementation(libs.converter.gson) diff --git a/app/src/main/java/com/aiosman/ravenow/ImageListScreen.kt b/app/src/main/java/com/aiosman/ravenow/ImageListScreen.kt index 0bf658d..c2b4603 100644 --- a/app/src/main/java/com/aiosman/ravenow/ImageListScreen.kt +++ b/app/src/main/java/com/aiosman/ravenow/ImageListScreen.kt @@ -7,11 +7,13 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp -import coil.compose.rememberAsyncImagePainter -import coil.request.ImageRequest -import coil.ImageLoader -import coil.disk.DiskCache -import coil.memory.MemoryCache +import coil3.ImageLoader +import coil3.compose.rememberAsyncImagePainter +import coil3.disk.DiskCache +import coil3.memory.MemoryCache +import coil3.request.ImageRequest +import coil3.request.crossfade +import okio.Path.Companion.toPath data class ImageItem(val url: String) @@ -53,14 +55,15 @@ fun ImageItem(item: ImageItem, imageLoader: ImageLoader, context: Context) { // fun getImageLoader(context: Context): ImageLoader { return ImageLoader.Builder(context) .memoryCache { - MemoryCache.Builder(context) - .maxSizePercent(0.25) // 设置内存缓存大小为可用内存的 25% + MemoryCache.Builder() + .maxSizePercent(context,0.25) // 设置内存缓存大小为可用内存的 25% .build() } .diskCache { + val cacheDir = context.cacheDir.resolve("image_cache") DiskCache.Builder() - .directory(context.cacheDir.resolve("image_cache")) - .maxSizePercent(0.02) // 设置磁盘缓存大小为可用存储空间的 2% + .directory(cacheDir.absolutePath.toPath()) + .maxSizeBytes(250L * 1024 * 1024) // 250MB .build() } .build() diff --git a/app/src/main/java/com/aiosman/ravenow/ui/about/AboutScreen.kt b/app/src/main/java/com/aiosman/ravenow/ui/about/AboutScreen.kt index e091155..59e50f5 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/about/AboutScreen.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/about/AboutScreen.kt @@ -71,7 +71,7 @@ fun AboutScreen() { Spacer(modifier = Modifier.height(16.dp)) // app version Text( - text = stringResource(R.string.version_text, versionText), + text = stringResource(R.string.version_text, versionText ?: ""), fontSize = 16.sp, color = appColors.secondaryText, fontWeight = FontWeight.Normal diff --git a/app/src/main/java/com/aiosman/ravenow/ui/comment/CommentModal.kt b/app/src/main/java/com/aiosman/ravenow/ui/comment/CommentModal.kt index c3483b7..9d53b78 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/comment/CommentModal.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/comment/CommentModal.kt @@ -118,8 +118,7 @@ fun CommentModalContent( skipPartiallyExpanded = true ), dragHandle = {}, - shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) + shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp) ) { CommentMenuModal( onDeleteClick = { diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/BlurHash.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/BlurHash.kt index c071ab2..7b1c5bf 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/BlurHash.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/BlurHash.kt @@ -8,9 +8,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.core.graphics.drawable.toDrawable -import coil.annotation.ExperimentalCoilApi -import coil.compose.AsyncImage -import coil.request.ImageRequest +import coil3.annotation.ExperimentalCoilApi +import coil3.compose.AsyncImage +import coil3.request.ImageRequest +import coil3.request.crossfade +import coil3.request.fallback +import coil3.request.placeholder import com.aiosman.ravenow.utils.BlurHashDecoder import com.aiosman.ravenow.utils.Utils.getImageLoader diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/DebounceUtils.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/DebounceUtils.kt index 4199840..e0238a4 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/DebounceUtils.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/DebounceUtils.kt @@ -2,6 +2,7 @@ package com.aiosman.ravenow.ui.composables import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.composed @@ -68,7 +69,6 @@ fun Modifier.debouncedClickableWithRipple( clickable( enabled = enabled && isClickable, interactionSource = remember { MutableInteractionSource() }, - indication = androidx.compose.material.ripple.rememberRipple() ) { if (isClickable) { isClickable = false diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/DragAndDrop.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/DragAndDrop.kt index be02b6c..d55101f 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/DragAndDrop.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/DragAndDrop.kt @@ -123,7 +123,7 @@ fun LazyGridItemScope.DraggableItem( translationY = dragDropState.previousItemOffset.value.y } } else { - Modifier.animateItemPlacement() + Modifier } Box(modifier = modifier.then(draggingModifier).clip(RoundedCornerShape(8.dp)), propagateMinConstraints = true) { content(dragging) diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/Image.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/Image.kt index b73d17d..628042b 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/Image.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/Image.kt @@ -16,11 +16,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toBitmap -import coil.ImageLoader -import coil.compose.AsyncImage -import coil.request.ImageRequest -import coil.request.SuccessResult +import coil3.ImageLoader +import coil3.asDrawable +import coil3.asImage +import coil3.compose.AsyncImage +import coil3.request.CachePolicy +import coil3.request.ImageRequest +import coil3.request.SuccessResult +import coil3.request.crossfade import com.aiosman.ravenow.utils.Utils.getImageLoader import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -59,7 +64,11 @@ fun rememberImageBitmap(imageUrl: String, imageLoader: ImageLoader): Bitmap? { .build() val result = withContext(Dispatchers.IO) { - (imageLoader.execute(request) as? SuccessResult)?.drawable?.toBitmap() + val successResult = imageLoader.execute(request) as? SuccessResult + successResult?.let { + val drawable = it.image.asDrawable(context.resources) + drawable.toBitmap() + } } bitmap = result @@ -138,25 +147,33 @@ fun CustomAsyncImage( } // 处理字符串URL + val ctx = context ?: localContext + val placeholderImage = remember(placeholderRes, ctx) { + placeholderRes?.let { resId -> + ContextCompat.getDrawable(ctx, resId)?.asImage() + } + } + val errorImage = remember(errorRes, ctx) { + errorRes?.let { resId -> + ContextCompat.getDrawable(ctx, resId)?.asImage() + } + } + if (showShimmer) { var isLoading by remember { mutableStateOf(true) } Box(modifier = modifier) { AsyncImage( - model = ImageRequest.Builder(context ?: localContext) + model = ImageRequest.Builder(ctx) .data(imageUrl) .crossfade(200) - .memoryCachePolicy(coil.request.CachePolicy.ENABLED) - .diskCachePolicy(coil.request.CachePolicy.ENABLED) + .memoryCachePolicy(coil3.request.CachePolicy.ENABLED) + .diskCachePolicy(coil3.request.CachePolicy.ENABLED) .apply { // 设置占位符图片 - if (placeholderRes != null) { - placeholder(placeholderRes) - } + placeholderImage?.let { placeholder(it) } // 设置错误时显示的图片 - if (errorRes != null) { - error(errorRes) - } + errorImage?.let { error(it) } } .build(), contentDescription = contentDescription, @@ -177,20 +194,16 @@ fun CustomAsyncImage( } } else { AsyncImage( - model = ImageRequest.Builder(context ?: localContext) + model = ImageRequest.Builder(ctx) .data(imageUrl) .crossfade(200) - .memoryCachePolicy(coil.request.CachePolicy.ENABLED) - .diskCachePolicy(coil.request.CachePolicy.ENABLED) + .memoryCachePolicy(CachePolicy.ENABLED) + .diskCachePolicy(CachePolicy.ENABLED) .apply { // 设置占位符图片 - if (placeholderRes != null) { - placeholder(placeholderRes) - } + placeholderImage?.let { placeholder(it) } // 设置错误时显示的图片 - if (errorRes != null) { - error(errorRes) - } + errorImage?.let { error(it) } } .build(), contentDescription = contentDescription, diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/Moment.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/Moment.kt index 131969d..8ba5163 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/Moment.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/Moment.kt @@ -450,7 +450,6 @@ fun MomentBottomOperateRowGroup( sheetState = rememberModalBottomSheetState( skipPartiallyExpanded = true ), - windowInsets = WindowInsets(0), dragHandle = { Box( modifier = Modifier diff --git a/app/src/main/java/com/aiosman/ravenow/ui/composables/PolicyCheckbox.kt b/app/src/main/java/com/aiosman/ravenow/ui/composables/PolicyCheckbox.kt index 9f09199..cc128a0 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/composables/PolicyCheckbox.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/composables/PolicyCheckbox.kt @@ -71,7 +71,6 @@ fun PolicyCheckbox( showModal = false }, sheetState = modalSheetState, - windowInsets = WindowInsets(0), containerColor = Color.White, ) { WebViewDisplay( diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/CreateBottomSheet.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/CreateBottomSheet.kt index f8ff1e5..f079332 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/CreateBottomSheet.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/CreateBottomSheet.kt @@ -47,7 +47,6 @@ fun CreateBottomSheet( ModalBottomSheet( onDismissRequest = onDismiss, sheetState = sheetState, - windowInsets = BottomSheetDefaults.windowInsets, containerColor = appColors.background, dragHandle = null, shape = RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp) diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/Index.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/Index.kt index 59e6beb..e3cd70b 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/Index.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/Index.kt @@ -265,7 +265,6 @@ fun IndexScreen() { modifier = Modifier .background(AppColors.background) .padding(0.dp), - beyondBoundsPageCount = 4, userScrollEnabled = false ) { page -> when (page) { diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/Agent.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/Agent.kt index 8392c97..2f0a56d 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/Agent.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/Agent.kt @@ -54,7 +54,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import com.aiosman.ravenow.AppStore import com.aiosman.ravenow.GuestLoginCheckOut @@ -115,7 +114,7 @@ fun Agent() { var pagerState = rememberPagerState { tabCount } var scope = rememberCoroutineScope() - val viewModel: AgentViewModel = viewModel() + val viewModel: AgentViewModel = AgentViewModel // 确保推荐Agent数据已加载 LaunchedEffect(Unit) { @@ -183,7 +182,6 @@ fun Agent() { colors = TopAppBarDefaults.topAppBarColors( containerColor = AppColors.background ), - windowInsets = WindowInsets(0, 0, 0, 0), modifier = Modifier .height(44.dp + statusBarPaddingValues.calculateTopPadding()) .padding(top = statusBarPaddingValues.calculateTopPadding()) @@ -899,7 +897,7 @@ fun ChatRoomCard( ) { val AppColors = LocalAppTheme.current val cardSize = 180.dp - val viewModel: AgentViewModel = viewModel() + val viewModel: AgentViewModel = AgentViewModel val context = LocalContext.current // 防抖状态 diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/tabs/hot/HotAgentViewModel.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/tabs/hot/HotAgentViewModel.kt index 44e11d2..a4625c0 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/tabs/hot/HotAgentViewModel.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/ai/tabs/hot/HotAgentViewModel.kt @@ -156,10 +156,10 @@ object HotAgentViewModel : ViewModel() { try { // 预加载头像图片到缓存 com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue( - coil.request.ImageRequest.Builder(context) + coil3.request.ImageRequest.Builder(context) .data(agent.avatar) - .memoryCachePolicy(coil.request.CachePolicy.ENABLED) - .diskCachePolicy(coil.request.CachePolicy.ENABLED) + .memoryCachePolicy(coil3.request.CachePolicy.ENABLED) + .diskCachePolicy(coil3.request.CachePolicy.ENABLED) .build() ) preloadedImageIds.add(agent.id) diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/expolre/Explore.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/expolre/Explore.kt index 29a041a..d5521ef 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/expolre/Explore.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/expolre/Explore.kt @@ -841,20 +841,20 @@ fun Explore() { if (bannerItem.backgroundImageUrl.isNotEmpty()) { // 预加载背景图片 com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue( - coil.request.ImageRequest.Builder(context) + coil3.request.ImageRequest.Builder(context) .data(bannerItem.backgroundImageUrl) - .memoryCachePolicy(coil.request.CachePolicy.ENABLED) - .diskCachePolicy(coil.request.CachePolicy.ENABLED) + .memoryCachePolicy(coil3.request.CachePolicy.ENABLED) + .diskCachePolicy(coil3.request.CachePolicy.ENABLED) .build() ) } if (bannerItem.imageUrl.isNotEmpty()) { // 预加载头像图片 com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue( - coil.request.ImageRequest.Builder(context) + coil3.request.ImageRequest.Builder(context) .data(bannerItem.imageUrl) - .memoryCachePolicy(coil.request.CachePolicy.ENABLED) - .diskCachePolicy(coil.request.CachePolicy.ENABLED) + .memoryCachePolicy(coil3.request.CachePolicy.ENABLED) + .diskCachePolicy(coil3.request.CachePolicy.ENABLED) .build() ) } diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/FullArticleModal.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/FullArticleModal.kt index 9a8ca45..15d8c1d 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/FullArticleModal.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/FullArticleModal.kt @@ -59,7 +59,6 @@ fun FullArticleModal( .height(sheetHeight), containerColor = appColors.background, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = androidx.compose.foundation.layout.WindowInsets(0) ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsCommentModal.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsCommentModal.kt index d46c8f6..8453000 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsCommentModal.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsCommentModal.kt @@ -154,7 +154,6 @@ fun NewsCommentModal( ), dragHandle = {}, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) ) { CommentMenuModal( onDeleteClick = { diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsScreen.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsScreen.kt index bbb2916..3137ff9 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsScreen.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/moment/tabs/news/NewsScreen.kt @@ -194,7 +194,6 @@ fun NewsScreen() { .height(sheetHeight), containerColor = AppColors.background, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = androidx.compose.foundation.layout.WindowInsets(0) ) { NewsCommentModal( postId = selectedMoment?.id, diff --git a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/profile/ProfileV3.kt b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/profile/ProfileV3.kt index 3f4864f..e1a0b67 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/profile/ProfileV3.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/index/tabs/profile/ProfileV3.kt @@ -258,7 +258,6 @@ fun ProfileV3( sheetState = agentMenuModalState, dragHandle = {}, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) ) { AgentMenuModal( agent = contextAgent, @@ -535,7 +534,7 @@ fun ProfileV3( containerColor = Color.Transparent, // 设置容器背景透明 contentColor = Color.Transparent, // 设置内容背景透明 dragHandle = null, // 移除拖拽手柄 - windowInsets = androidx.compose.foundation.layout.WindowInsets(0) // 移除窗口边距 + contentWindowInsets = {androidx.compose.foundation.layout.WindowInsets(0)}, ) { Box( modifier = Modifier @@ -567,7 +566,7 @@ fun ProfileV3( containerColor = Color.Transparent, contentColor = Color.Transparent, dragHandle = null, - windowInsets = androidx.compose.foundation.layout.WindowInsets(0) + contentWindowInsets = { androidx.compose.foundation.layout.WindowInsets(0) } ) { Box( modifier = Modifier diff --git a/app/src/main/java/com/aiosman/ravenow/ui/location/LocationDetailScreen.kt b/app/src/main/java/com/aiosman/ravenow/ui/location/LocationDetailScreen.kt index fcafef7..4fc169c 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/location/LocationDetailScreen.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/location/LocationDetailScreen.kt @@ -114,11 +114,14 @@ fun getFeedItems(): List { @Composable fun LocationDetailScreen(x: Float, y: Float) { val scope = rememberCoroutineScope() + val density = LocalDensity.current val scaffoldState = rememberBottomSheetScaffoldState( - SheetState( + bottomSheetState = SheetState( skipPartiallyExpanded = false, - density = LocalDensity.current, initialValue = SheetValue.PartiallyExpanded, - skipHiddenState = true + initialValue = SheetValue.PartiallyExpanded, + skipHiddenState = true, + positionalThreshold = { 0.5f }, + velocityThreshold = { with(density) { 125.dp.toPx() } } ) ) val configuration = LocalConfiguration.current diff --git a/app/src/main/java/com/aiosman/ravenow/ui/post/NewPostImageGrid.kt b/app/src/main/java/com/aiosman/ravenow/ui/post/NewPostImageGrid.kt index c6b4cc9..3a671a7 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/post/NewPostImageGrid.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/post/NewPostImageGrid.kt @@ -22,6 +22,7 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Delete + import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment @@ -30,7 +31,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import coil.compose.rememberAsyncImagePainter +import coil3.compose.rememberAsyncImagePainter import com.aiosman.ravenow.LocalNavController import com.aiosman.ravenow.ui.modifiers.noRippleClickable import com.google.accompanist.systemuicontroller.rememberSystemUiController @@ -67,7 +68,7 @@ fun NewPostImageGridScreen() { verticalAlignment = Alignment.CenterVertically ) { Icon( - Icons.AutoMirrored.Default.ArrowBack, + Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "back", modifier = Modifier .size(24.dp) @@ -84,7 +85,7 @@ fun NewPostImageGridScreen() { fontSize = 18.sp, ) Icon( - Icons.Default.Delete, + Icons.Filled.Delete, contentDescription = "delete", modifier = Modifier .size(24.dp) diff --git a/app/src/main/java/com/aiosman/ravenow/ui/post/Post.kt b/app/src/main/java/com/aiosman/ravenow/ui/post/Post.kt index 8316153..c022305 100644 --- a/app/src/main/java/com/aiosman/ravenow/ui/post/Post.kt +++ b/app/src/main/java/com/aiosman/ravenow/ui/post/Post.kt @@ -173,7 +173,6 @@ fun PostScreen( sheetState = commentModalState, dragHandle = {}, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) ) { CommentMenuModal( onDeleteClick = { @@ -262,7 +261,6 @@ fun PostScreen( ), dragHandle = {}, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) ) { EditCommentBottomModal(replyComment) { viewModel.viewModelScope.launch { @@ -849,7 +847,6 @@ fun Header( ), dragHandle = {}, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), - windowInsets = WindowInsets(0) ) { PostMenuModal( diff --git a/app/src/main/java/com/aiosman/ravenow/utils/FileUtil.kt b/app/src/main/java/com/aiosman/ravenow/utils/FileUtil.kt index 6e95cc8..e90fd11 100644 --- a/app/src/main/java/com/aiosman/ravenow/utils/FileUtil.kt +++ b/app/src/main/java/com/aiosman/ravenow/utils/FileUtil.kt @@ -4,14 +4,16 @@ import android.content.ContentValues import android.content.Context import android.database.Cursor import android.graphics.Bitmap -import android.graphics.drawable.BitmapDrawable import android.net.Uri import android.os.Build import android.os.Environment import android.provider.MediaStore import android.widget.Toast -import coil.request.ImageRequest -import coil.request.SuccessResult +import androidx.core.graphics.drawable.toBitmap +import coil3.asDrawable +import coil3.request.ImageRequest +import coil3.request.SuccessResult +import coil3.request.allowHardware import com.aiosman.ravenow.utils.Utils.getImageLoader import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -30,8 +32,9 @@ object FileUtil { .allowHardware(false) // Disable hardware bitmaps. .build() - val result = (loader.execute(request) as SuccessResult).drawable - val bitmap = (result as BitmapDrawable).bitmap + val result = loader.execute(request) as? SuccessResult ?: return + val drawable = result.image.asDrawable(context.resources) + val bitmap = drawable.toBitmap() val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, "image_${System.currentTimeMillis()}.jpg") diff --git a/app/src/main/java/com/aiosman/ravenow/utils/Utils.kt b/app/src/main/java/com/aiosman/ravenow/utils/Utils.kt index 7ed2cce..f47c465 100644 --- a/app/src/main/java/com/aiosman/ravenow/utils/Utils.kt +++ b/app/src/main/java/com/aiosman/ravenow/utils/Utils.kt @@ -4,8 +4,9 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri -import coil.ImageLoader -import coil.request.CachePolicy +import coil3.ImageLoader +import coil3.network.okhttp.OkHttpNetworkFetcherFactory +import coil3.request.CachePolicy import com.aiosman.ravenow.data.api.AuthInterceptor import com.aiosman.ravenow.data.api.getSafeOkHttpClient import java.io.File @@ -32,7 +33,15 @@ object Utils { val okHttpClient = getSafeOkHttpClient(authInterceptor = AuthInterceptor()) val loader = ImageLoader.Builder(appContext) - .okHttpClient(okHttpClient) + .components { + add( + OkHttpNetworkFetcherFactory( + callFactory = { + okHttpClient + } + ) + ) + } .memoryCachePolicy(CachePolicy.ENABLED) .diskCachePolicy(CachePolicy.ENABLED) .build() diff --git a/build.gradle.kts b/build.gradle.kts index 0d60e7b..66f3513 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.jetbrains.kotlin.android) apply false + alias(libs.plugins.compose.compiler) apply false id("com.google.gms.google-services") version "4.4.2" apply false id("com.google.firebase.crashlytics") version "3.0.2" apply false id("com.google.firebase.firebase-perf") version "1.4.2" apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aea504a..51eb923 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,48 +1,51 @@ [versions] -accompanistSystemuicontroller = "0.27.0" -agp = "8.4.0" -animation = "1.7.0-beta05" -coil = "2.7.0" +accompanistSystemuicontroller = "0.34.0" +agp = "8.9.0" +animation = "1.7.6" +coil = "3.3.0" composeImageBlurhash = "3.0.2" converterGson = "2.11.0" imSdk = "3.8.3.2" imcoreSdk = "3.8.3-patch10" -coreSplashscreen = "1.0.1" -credentialsPlayServicesAuth = "1.2.2" +coreSplashscreen = "1.2.0" +credentialsPlayServicesAuth = "1.0.0-alpha05" eventbus = "3.3.1" -firebaseBom = "33.2.0" +firebaseBom = "33.7.0" gson = "2.12.1" imagecropview = "3.0.1" jpushGoogle = "5.4.0" jwtdecode = "2.0.2" -kotlin = "1.9.10" -coreKtx = "1.10.1" +kotlin = "2.2.21" +ksp = "2.2.21-2.0.4" +composeCompiler = "2.2.21" +coreKtx = "1.15.0" junit = "4.13.2" -junitVersion = "1.1.5" -espressoCore = "3.5.1" -kotlinFaker = "2.0.0-rc.5" -lifecycleRuntimeKtx = "2.6.1" -activityCompose = "1.8.0" -composeBom = "2024.06.00" -lifecycleRuntimeKtxVersion = "2.6.2" -mapsCompose = "4.3.3" -material = "1.6.8" -material3Android = "1.2.1" -media3Exoplayer = "1.3.1" -navigationCompose = "2.7.7" -pagingRuntime = "3.3.0" -activityKtx = "1.9.0" -lifecycleCommonJvm = "2.8.2" -places = "3.3.0" +junitVersion = "1.2.1" +espressoCore = "3.6.1" +kotlinFaker = "2.0.0-rc.11" +lifecycleRuntimeKtx = "2.8.6" +activityCompose = "1.9.2" +composeBom = "2025.11.00" +lifecycleRuntimeKtxVersion = "2.8.6" +mapsCompose = "6.1.0" +material = "1.7.6" +materialIconsExtended = "1.7.6" +material3Android = "1.3.1" +media3Exoplayer = "1.4.1" +navigationCompose = "2.8.6" +pagingRuntime = "3.3.6" +activityKtx = "1.9.2" +lifecycleCommonJvm = "2.8.6" +places = "3.4.0" googleid = "1.1.1" identityCredential = "20231002" -lifecycleProcess = "2.8.4" +lifecycleProcess = "2.8.6" playServicesAuth = "21.4.0" rendering = "1.17.1" zoomable = "1.6.1" -camerax = "1.3.4" +camerax = "1.4.0" mlkitBarcode = "17.3.0" -room = "2.6.1" +room = "2.8.3" [libraries] accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanistSystemuicontroller" } @@ -53,6 +56,7 @@ androidx-credentials = { module = "androidx.credentials:credentials", version.re androidx-credentials-play-services-auth = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "credentialsPlayServicesAuth" } androidx-lifecycle-runtime-ktx-v262 = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtxVersion" } androidx-material = { module = "androidx.compose.material:material", version.ref = "material" } +androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsExtended" } androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3Exoplayer" } androidx-media3-session = { module = "androidx.media3:media3-session", version.ref = "media3Exoplayer" } androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3Exoplayer" } @@ -62,8 +66,9 @@ androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version.r androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" } androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camerax" } androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" } -coil = { module = "io.coil-kt:coil", version.ref = "coil" } -coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } +coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } +coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } +coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } compose-image-blurhash = { module = "com.github.orlando-dev-code:compose-image-blurhash", version.ref = "composeImageBlurhash" } converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" } eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" } @@ -79,7 +84,7 @@ junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } -androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.9.0" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } androidx-ui = { group = "androidx.compose.ui", name = "ui" } androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } @@ -104,7 +109,7 @@ play-services-auth = { module = "com.google.android.gms:play-services-auth", ver rendering = { group = "com.google.ar.sceneform", name = "rendering", version.ref = "rendering" } retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "converterGson" } zoomable = { module = "net.engawapg.lib:zoomable", version.ref = "zoomable" } -lottie = { module="com.airbnb.android:lottie-compose", version="6.6.10"} +lottie = { module="com.airbnb.android:lottie-compose", version="6.7.0"} mlkit-barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "mlkitBarcode" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } @@ -112,3 +117,5 @@ androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = [plugins] android-application = { id = "com.android.application", version.ref = "agp" } jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "composeCompiler" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 537d502..8635977 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Jun 14 03:23:01 CST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists