Fix several deprecation notices (#758)

* migrate to Gradle Kotlin DSL, version catalog and ksp

* replace buildDir with layout.buildDirectory

* declare plugins in version catalogs

* add room plugin

* specify type of keyPropsFile

* added missing version number in [versions]

* use alias instead of id whenever possible

* finishes replacing id with alias

* migrate pager

* Migrate to androidx.compose.foundation FlowLayouts

* add optin to avoid warning during build

* use nonFinalResIds for faster compilation

* use nonTransitiveRclass for faster compilation

* migrate smallTopAppBarColors to topAppBarColors

* migrate 'with(ExitTransition): ContentTransform' to togetherWith

* migrate fromHtml

* migrate TextFieldDefaults.textFieldColors to TextFieldDefaults.colors

* migrate get(...).toString() to getString(...)

* add optin

* rename Divider to HorizontalDivider
This commit is contained in:
aualbert 2024-06-19 09:09:00 +00:00 committed by GitHub
parent 573fead2da
commit 81dbe094f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 54 additions and 81 deletions

View File

@ -2,7 +2,7 @@ import java.util.Properties
import java.io.FileInputStream import java.io.FileInputStream
plugins { plugins {
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.aboutlibraries) alias(libs.plugins.aboutlibraries)
@ -130,8 +130,6 @@ dependencies {
implementation(libs.compose.material3) implementation(libs.compose.material3)
// Accompanist // Accompanist
implementation(libs.accompanist.pager)
implementation(libs.accompanist.flowlayout)
implementation(libs.accompanist.swiperefresh) implementation(libs.accompanist.swiperefresh)
// Coil // Coil

View File

@ -46,7 +46,7 @@ fun AnimatedText(
200, 200,
easing = FastOutSlowInEasing easing = FastOutSlowInEasing
) )
) { height -> height } with slideOutVertically { height -> -height } + fadeOut( ) { height -> height } togetherWith slideOutVertically { height -> -height } + fadeOut(
tween( tween(
200, 200,
easing = FastOutSlowInEasing easing = FastOutSlowInEasing

View File

@ -60,8 +60,9 @@ fun RYOutlineTextField(
OutlinedTextField( OutlinedTextField(
modifier = Modifier.focusRequester(focusRequester), modifier = Modifier.focusRequester(focusRequester),
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.colors(
containerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
focusedContainerColor = Color.Transparent
), ),
maxLines = if (singleLine) 1 else Int.MAX_VALUE, maxLines = if (singleLine) 1 else Int.MAX_VALUE,
enabled = !readOnly, enabled = !readOnly,

View File

@ -44,7 +44,7 @@ fun RYScaffold(
title = {}, title = {},
navigationIcon = { navigationIcon?.invoke() }, navigationIcon = { navigationIcon?.invoke() },
actions = { actions?.invoke(this) }, actions = { actions?.invoke(this) },
colors = TopAppBarDefaults.smallTopAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation topBarTonalElevation
), ),

View File

@ -46,8 +46,9 @@ fun RYTextField(
TextField( TextField(
modifier = Modifier.focusRequester(focusRequester), modifier = Modifier.focusRequester(focusRequester),
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.colors(
containerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent,
focusedContainerColor = Color.Transparent
), ),
maxLines = if (singleLine) 1 else Int.MAX_VALUE, maxLines = if (singleLine) 1 else Int.MAX_VALUE,
enabled = !readOnly, enabled = !readOnly,

View File

@ -1,26 +1,24 @@
package me.ash.reader.ui.component.base package me.ash.reader.ui.component.base
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.PagerState
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun ViewPager( fun ViewPager(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
state: PagerState = com.google.accompanist.pager.rememberPagerState(),
composableList: List<@Composable () -> Unit>, composableList: List<@Composable () -> Unit>,
userScrollEnabled: Boolean = true, userScrollEnabled: Boolean = true,
) { ) {
HorizontalPager( HorizontalPager(
count = composableList.size, state = rememberPagerState { composableList.size },
state = state,
verticalAlignment = Alignment.Top, verticalAlignment = Alignment.Top,
modifier = modifier modifier = modifier
.animateContentSize() .animateContentSize()

View File

@ -19,30 +19,18 @@ import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.lerp import androidx.compose.ui.unit.lerp
import com.google.accompanist.pager.ExperimentalPagerApi import androidx.compose.foundation.pager.PagerState
import com.google.accompanist.pager.PagerScope
import com.google.accompanist.pager.calculateCurrentOffsetForPage
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalFoundationApi::class)
fun Modifier.pagerAnimate(pagerScope: PagerScope, page: Int): Modifier { fun Modifier.pagerAnimate(pagerState: PagerState, page: Int): Modifier {
return graphicsLayer { return graphicsLayer {
// Calculate the absolute offset for the current page from the // Calculate the absolute offset for the current page from the
// scroll position. We use the absolute value which allows us to mirror // scroll position. We use the absolute value which allows us to mirror
// any effects for both directions // any effects for both directions
val pageOffset = pagerScope.calculateCurrentOffsetForPage(page).absoluteValue val pageOffset = ((pagerState.currentPage - page) + pagerState.currentPageOffsetFraction).absoluteValue
// We animate the scaleX + scaleY, between 85% and 100% // We animate the alpha, between 20% and 100%
// lerp(
// start = 0.85f.dp,
// stop = 1f.dp,
// fraction = 1f - pageOffset.coerceIn(0f, 1f)
// ).also { scale ->
// scaleX = scale.value
// scaleY = scale.value
// }
// We animate the alpha, between 50% and 100%
alpha = lerp( alpha = lerp(
start = 0.2f.dp, start = 0.2f.dp,
stop = 1f.dp, stop = 1f.dp,

View File

@ -1,11 +1,11 @@
package me.ash.reader.ui.ext package me.ash.reader.ui.ext
import com.google.accompanist.pager.ExperimentalPagerApi import androidx.compose.foundation.ExperimentalFoundationApi
import com.google.accompanist.pager.PagerState import androidx.compose.foundation.pager.PagerState
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalFoundationApi::class)
fun PagerState.animateScrollToPage( fun PagerState.animateScrollToPage(
scope: CoroutineScope, scope: CoroutineScope,
targetPage: Int, targetPage: Int,

View File

@ -43,7 +43,7 @@ fun String.md5(): String =
BigInteger(1, MessageDigest.getInstance("MD5").digest(toByteArray())) BigInteger(1, MessageDigest.getInstance("MD5").digest(toByteArray()))
.toString(16).padStart(32, '0') .toString(16).padStart(32, '0')
fun String?.decodeHTML(): String? = this?.run { Html.fromHtml(this).toString() } fun String?.decodeHTML(): String? = this?.run { Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY).toString() }
fun String?.orNotEmpty(l: (value: String) -> String): String = fun String?.orNotEmpty(l: (value: String) -> String): String =
if (this.isNullOrBlank()) "" else l(this) if (this.isNullOrBlank()) "" else l(this)

View File

@ -69,7 +69,7 @@ fun HomeEntry(
val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) } val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) }
var openArticleId by rememberSaveable { var openArticleId by rememberSaveable {
mutableStateOf(intent?.extras?.get(ExtraName.ARTICLE_ID)?.toString() ?: "") mutableStateOf(intent?.extras?.getString(ExtraName.ARTICLE_ID) ?: "")
}.also { }.also {
intent?.replaceExtras(null) intent?.replaceExtras(null)
} }

View File

@ -9,7 +9,6 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Article import androidx.compose.material.icons.automirrored.outlined.Article
import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Article
import androidx.compose.material.icons.outlined.Notifications import androidx.compose.material.icons.outlined.Notifications
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -22,9 +21,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.google.accompanist.flowlayout.FlowCrossAxisAlignment import androidx.compose.foundation.layout.FlowRow
import com.google.accompanist.flowlayout.FlowRow
import com.google.accompanist.flowlayout.MainAxisAlignment
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.domain.model.group.Group import me.ash.reader.domain.model.group.Group
import me.ash.reader.ui.component.base.RYSelectionChip import me.ash.reader.ui.component.base.RYSelectionChip
@ -119,6 +116,7 @@ private fun EditableUrl(
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
private fun Preset( private fun Preset(
selectedAllowNotificationPreset: Boolean = false, selectedAllowNotificationPreset: Boolean = false,
@ -133,10 +131,8 @@ private fun Preset(
Subtitle(text = stringResource(R.string.preset)) Subtitle(text = stringResource(R.string.preset))
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
FlowRow( FlowRow(
mainAxisAlignment = MainAxisAlignment.Start, horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
crossAxisAlignment = FlowCrossAxisAlignment.Center, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
crossAxisSpacing = 10.dp,
mainAxisSpacing = 10.dp,
) { ) {
RYSelectionChip( RYSelectionChip(
modifier = Modifier.animateContentSize(), modifier = Modifier.animateContentSize(),
@ -193,6 +189,7 @@ private fun Preset(
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
private fun AddToGroup( private fun AddToGroup(
isMoveToGroup: Boolean = false, isMoveToGroup: Boolean = false,
@ -222,10 +219,8 @@ private fun AddToGroup(
} }
} else { } else {
FlowRow( FlowRow(
mainAxisAlignment = MainAxisAlignment.Start, horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
crossAxisAlignment = FlowCrossAxisAlignment.Center, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
crossAxisSpacing = 10.dp,
mainAxisSpacing = 10.dp,
) { ) {
groups.forEach { groups.forEach {
RYSelectionChip( RYSelectionChip(

View File

@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
@ -39,6 +40,7 @@ class FeedsViewModel @Inject constructor(
} }
} }
@OptIn(ExperimentalCoroutinesApi::class)
fun pullFeeds(filterState: FilterState) { fun pullFeeds(filterState: FilterState) {
val isStarred = filterState.filter.isStarred() val isStarred = filterState.filter.isStarred()
val isUnread = filterState.filter.isUnread() val isUnread = filterState.filter.isUnread()

View File

@ -22,15 +22,14 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.google.accompanist.flowlayout.FlowCrossAxisAlignment import androidx.compose.foundation.layout.FlowRow
import com.google.accompanist.flowlayout.FlowRow
import com.google.accompanist.flowlayout.MainAxisAlignment
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.domain.model.account.Account import me.ash.reader.domain.model.account.Account
import me.ash.reader.ui.component.base.RYDialog import me.ash.reader.ui.component.base.RYDialog
import me.ash.reader.ui.ext.currentAccountId import me.ash.reader.ui.ext.currentAccountId
import me.ash.reader.ui.theme.palette.alwaysLight import me.ash.reader.ui.theme.palette.alwaysLight
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
fun AccountsTab( fun AccountsTab(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -58,10 +57,8 @@ fun AccountsTab(
}, },
text = { text = {
FlowRow( FlowRow(
mainAxisAlignment = MainAxisAlignment.Start, horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
crossAxisAlignment = FlowCrossAxisAlignment.Start, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
crossAxisSpacing = 10.dp,
mainAxisSpacing = 10.dp,
) { ) {
accounts.forEach { account -> accounts.forEach { account ->
Column( Column(

View File

@ -27,9 +27,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.google.accompanist.flowlayout.FlowCrossAxisAlignment import androidx.compose.foundation.layout.FlowRow
import com.google.accompanist.flowlayout.FlowRow
import com.google.accompanist.flowlayout.MainAxisAlignment
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.domain.model.group.Group import me.ash.reader.domain.model.group.Group
@ -149,6 +147,7 @@ fun GroupOptionDrawer(
) )
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
private fun Preset( private fun Preset(
viewModel: GroupOptionViewModel, viewModel: GroupOptionViewModel,
@ -156,10 +155,8 @@ private fun Preset(
context: Context, context: Context,
) { ) {
FlowRow( FlowRow(
mainAxisAlignment = MainAxisAlignment.Start, horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
crossAxisAlignment = FlowCrossAxisAlignment.Center, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
crossAxisSpacing = 10.dp,
mainAxisSpacing = 10.dp,
) { ) {
RYSelectionChip( RYSelectionChip(
modifier = Modifier.animateContentSize(), modifier = Modifier.animateContentSize(),
@ -212,6 +209,7 @@ private fun Preset(
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
private fun FlowRowGroups( private fun FlowRowGroups(
groupOptionUiState: GroupOptionUiState, groupOptionUiState: GroupOptionUiState,
@ -219,10 +217,8 @@ private fun FlowRowGroups(
groupOptionViewModel: GroupOptionViewModel, groupOptionViewModel: GroupOptionViewModel,
) { ) {
FlowRow( FlowRow(
mainAxisAlignment = MainAxisAlignment.Start, horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
crossAxisAlignment = FlowCrossAxisAlignment.Center, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically),
crossAxisSpacing = 10.dp,
mainAxisSpacing = 10.dp,
) { ) {
groupOptionUiState.groups.forEach { groupOptionUiState.groups.forEach {
if (it.id != group?.id) { if (it.id != group?.id) {

View File

@ -8,6 +8,7 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.animation.with import androidx.compose.animation.with
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@ -104,8 +105,8 @@ fun SubscribeDialog(
AnimatedContent( AnimatedContent(
targetState = subscribeUiState.isSearchPage, targetState = subscribeUiState.isSearchPage,
transitionSpec = { transitionSpec = {
slideInHorizontally { width -> width } + fadeIn() with (slideInHorizontally { width -> width } + fadeIn()).togetherWith(
slideOutHorizontally { width -> -width } + fadeOut() slideOutHorizontally { width -> -width } + fadeOut())
} }
) { targetExpanded -> ) { targetExpanded ->
if (targetExpanded) { if (targetExpanded) {

View File

@ -61,7 +61,6 @@ import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.home.HomeViewModel import me.ash.reader.ui.page.home.HomeViewModel
@OptIn( @OptIn(
com.google.accompanist.pager.ExperimentalPagerApi::class,
androidx.compose.ui.ExperimentalComposeUiApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class,
) )
@Composable @Composable

View File

@ -81,7 +81,7 @@ fun TopBar(
) { ) {
sharedContent.share(context, title, link) sharedContent.share(context, title, link)
} }
}, colors = TopAppBarDefaults.smallTopAppBarColors( }, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(tonalElevation.value.dp), containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(tonalElevation.value.dp),
) )
) )

View File

@ -85,11 +85,11 @@ fun SettingItem(
} }
action?.let { action?.let {
if (separatedActions) { if (separatedActions) {
Divider( HorizontalDivider(
modifier = Modifier modifier = Modifier
.padding(start = 16.dp) .padding(start = 16.dp)
.size(1.dp, 32.dp), .size(1.dp, 32.dp),
color = tonalPalettes neutralVariant 80 onDark (tonalPalettes neutralVariant 30), color = tonalPalettes neutralVariant 80 onDark (tonalPalettes neutralVariant 30)
) )
} }
Box(Modifier.padding(start = 16.dp)) { Box(Modifier.padding(start = 16.dp)) {

View File

@ -88,7 +88,7 @@ fun FeedsPagePreview(
contentDescription = stringResource(R.string.subscribe), contentDescription = stringResource(R.string.subscribe),
tint = MaterialTheme.colorScheme.onSurface, tint = MaterialTheme.colorScheme.onSurface,
) )
}, colors = TopAppBarDefaults.smallTopAppBarColors( }, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation.value.dp topBarTonalElevation.value.dp
), ),

View File

@ -26,7 +26,6 @@ import me.ash.reader.domain.model.feed.Feed
import me.ash.reader.domain.model.general.Filter import me.ash.reader.domain.model.general.Filter
import me.ash.reader.infrastructure.preference.FlowArticleListTonalElevationPreference import me.ash.reader.infrastructure.preference.FlowArticleListTonalElevationPreference
import me.ash.reader.infrastructure.preference.FlowTopBarTonalElevationPreference import me.ash.reader.infrastructure.preference.FlowTopBarTonalElevationPreference
import me.ash.reader.infrastructure.preference.LocalDarkTheme
import me.ash.reader.ui.component.FilterBar import me.ash.reader.ui.component.FilterBar
import me.ash.reader.ui.component.base.FeedbackIconButton import me.ash.reader.ui.component.base.FeedbackIconButton
import me.ash.reader.ui.ext.surfaceColorAtElevation import me.ash.reader.ui.ext.surfaceColorAtElevation
@ -76,7 +75,7 @@ fun FlowPagePreview(
contentDescription = stringResource(R.string.search), contentDescription = stringResource(R.string.search),
tint = MaterialTheme.colorScheme.onSurface, tint = MaterialTheme.colorScheme.onSurface,
) {} ) {}
}, colors = TopAppBarDefaults.smallTopAppBarColors( }, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation.value.dp topBarTonalElevation.value.dp
), ),

View File

@ -73,8 +73,6 @@ compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4
compose-material3 = { group = "androidx.compose.material3", name = "material3" } compose-material3 = { group = "androidx.compose.material3", name = "material3" }
# Accompanist # Accompanist
accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanist" }
accompanist-flowlayout = { group = "com.google.accompanist", name = "accompanist-flowlayout", version.ref = "accompanist" }
accompanist-swiperefresh = { group = "com.google.accompanist", name = "accompanist-swiperefresh", version.ref = "accompanist" } accompanist-swiperefresh = { group = "com.google.accompanist", name = "accompanist-swiperefresh", version.ref = "accompanist" }
# Coil # Coil