Migrate Accompanist SwipeRefresh to Compose PullRefresh (#8106)

This commit is contained in:
stevenyomi 2022-12-08 11:40:57 +08:00 committed by GitHub
parent 6ca32710be
commit 2c4ddca38e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 59 deletions

View file

@ -179,7 +179,6 @@ dependencies {
implementation(compose.ui.tooling) implementation(compose.ui.tooling)
implementation(compose.ui.util) implementation(compose.ui.util)
implementation(compose.accompanist.webview) implementation(compose.accompanist.webview)
implementation(compose.accompanist.swiperefresh)
implementation(compose.accompanist.flowlayout) implementation(compose.accompanist.flowlayout)
implementation(compose.accompanist.permissions) implementation(compose.accompanist.permissions)
implementation(compose.accompanist.themeadapter) implementation(compose.accompanist.themeadapter)
@ -325,6 +324,7 @@ tasks {
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi", "-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi", "-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api", "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi", "-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi", "-opt-in=androidx.compose.animation.ExperimentalAnimationApi",

View file

@ -40,7 +40,7 @@ import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.components.EmptyScreen import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.FastScrollLazyColumn import eu.kanade.presentation.components.FastScrollLazyColumn
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.components.PullRefresh
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.presentation.theme.header import eu.kanade.presentation.theme.header
import eu.kanade.presentation.util.padding import eu.kanade.presentation.util.padding
@ -68,7 +68,7 @@ fun ExtensionScreen(
onClickUpdateAll: () -> Unit, onClickUpdateAll: () -> Unit,
onRefresh: () -> Unit, onRefresh: () -> Unit,
) { ) {
SwipeRefresh( PullRefresh(
refreshing = state.isRefreshing, refreshing = state.isRefreshing,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = !state.isLoading, enabled = !state.isLoading,

View file

@ -309,7 +309,7 @@ private fun Modifier.selectedOutline(
} }
return this then modifierElementOf( return this then modifierElementOf(
params = isSelected.hashCode() + color.hashCode(), key = isSelected.hashCode() + color.hashCode(),
create = { SelectedOutlineNode(isSelected, color) }, create = { SelectedOutlineNode(isSelected, color) },
update = { update = {
it.selected = isSelected it.selected = isSelected

View file

@ -0,0 +1,50 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.unit.dp
/**
* Code reference: [Accompanist SwipeRefresh](https://github.com/google/accompanist/blob/677bc4ca0ee74677a8ba73793d04d85fe4ab55fb/swiperefresh/src/main/java/com/google/accompanist/swiperefresh/SwipeRefresh.kt#L265-L283)
*/
@Composable
fun PullRefresh(
refreshing: Boolean,
onRefresh: () -> Unit,
enabled: Boolean,
indicatorPadding: PaddingValues = PaddingValues(0.dp),
content: @Composable () -> Unit,
) {
val state = rememberPullRefreshState(
refreshing = refreshing,
onRefresh = onRefresh,
)
Box(Modifier.pullRefresh(state, enabled)) {
content()
Box(
Modifier
.padding(indicatorPadding)
.matchParentSize()
.clipToBounds(),
) {
PullRefreshIndicator(
refreshing = refreshing,
state = state,
modifier = Modifier.align(Alignment.TopCenter),
backgroundColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary,
)
}
}
}

View file

@ -1,44 +0,0 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.google.accompanist.swiperefresh.SwipeRefreshState
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator as AccompanistSwipeRefreshIndicator
@Composable
fun SwipeRefreshIndicator(
state: SwipeRefreshState,
refreshTriggerDistance: Dp,
refreshingOffset: Dp = 16.dp,
) {
AccompanistSwipeRefreshIndicator(
state = state,
refreshTriggerDistance = refreshTriggerDistance,
backgroundColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary,
refreshingOffset = refreshingOffset,
)
}
@Composable
fun SwipeRefresh(
refreshing: Boolean,
onRefresh: () -> Unit,
enabled: Boolean,
indicatorPadding: PaddingValues = PaddingValues(0.dp),
content: @Composable () -> Unit,
) {
com.google.accompanist.swiperefresh.SwipeRefresh(
state = rememberSwipeRefreshState(refreshing),
onRefresh = onRefresh,
swipeEnabled = enabled,
indicatorPadding = indicatorPadding,
indicator = { s, trigger -> SwipeRefreshIndicator(s, trigger) },
) {
content()
}
}

View file

@ -18,7 +18,7 @@ import eu.kanade.core.prefs.PreferenceMutableState
import eu.kanade.domain.category.model.Category import eu.kanade.domain.category.model.Category
import eu.kanade.domain.library.model.LibraryDisplayMode import eu.kanade.domain.library.model.LibraryDisplayMode
import eu.kanade.domain.library.model.LibraryManga import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.components.PullRefresh
import eu.kanade.presentation.components.rememberPagerState import eu.kanade.presentation.components.rememberPagerState
import eu.kanade.tachiyomi.ui.library.LibraryItem import eu.kanade.tachiyomi.ui.library.LibraryItem
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -79,11 +79,11 @@ fun LibraryContent(
} }
} }
SwipeRefresh( PullRefresh(
refreshing = isRefreshing, refreshing = isRefreshing,
onRefresh = { onRefresh = {
val started = onRefresh(categories[currentPage()]) val started = onRefresh(categories[currentPage()])
if (!started) return@SwipeRefresh if (!started) return@PullRefresh
scope.launch { scope.launch {
// Fake refresh status but hide it after a second as it's a long running task // Fake refresh status but hide it after a second as it's a long running task
isRefreshing = true isRefreshing = true

View file

@ -51,8 +51,8 @@ import eu.kanade.presentation.components.ChapterDownloadAction
import eu.kanade.presentation.components.ExtendedFloatingActionButton import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.presentation.components.LazyColumn import eu.kanade.presentation.components.LazyColumn
import eu.kanade.presentation.components.MangaBottomActionMenu import eu.kanade.presentation.components.MangaBottomActionMenu
import eu.kanade.presentation.components.PullRefresh
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.SwipeRefresh
import eu.kanade.presentation.components.TwoPanelBox import eu.kanade.presentation.components.TwoPanelBox
import eu.kanade.presentation.components.VerticalFastScroller import eu.kanade.presentation.components.VerticalFastScroller
import eu.kanade.presentation.manga.components.ChapterHeader import eu.kanade.presentation.manga.components.ChapterHeader
@ -287,7 +287,7 @@ private fun MangaScreenSmallImpl(
) { contentPadding -> ) { contentPadding ->
val topPadding = contentPadding.calculateTopPadding() val topPadding = contentPadding.calculateTopPadding()
SwipeRefresh( PullRefresh(
refreshing = state.isRefreshingData, refreshing = state.isRefreshingData,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = chapters.fastAll { !it.selected }, enabled = chapters.fastAll { !it.selected },
@ -421,7 +421,7 @@ fun MangaScreenLargeImpl(
val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues() val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues()
var topBarHeight by remember { mutableStateOf(0) } var topBarHeight by remember { mutableStateOf(0) }
SwipeRefresh( PullRefresh(
refreshing = state.isRefreshingData, refreshing = state.isRefreshingData,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = chapters.fastAll { !it.selected }, enabled = chapters.fastAll { !it.selected },

View file

@ -29,8 +29,8 @@ import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.FastScrollLazyColumn import eu.kanade.presentation.components.FastScrollLazyColumn
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.MangaBottomActionMenu import eu.kanade.presentation.components.MangaBottomActionMenu
import eu.kanade.presentation.components.PullRefresh
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.SwipeRefresh
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.updates.UpdatesItem import eu.kanade.tachiyomi.ui.updates.UpdatesItem
@ -96,11 +96,11 @@ fun UpdateScreen(
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var isRefreshing by remember { mutableStateOf(false) } var isRefreshing by remember { mutableStateOf(false) }
SwipeRefresh( PullRefresh(
refreshing = isRefreshing, refreshing = isRefreshing,
onRefresh = { onRefresh = {
val started = onUpdateLibrary() val started = onUpdateLibrary()
if (!started) return@SwipeRefresh if (!started) return@PullRefresh
scope.launch { scope.launch {
// Fake refresh status but hide it after a second as it's a long running task // Fake refresh status but hide it after a second as it's a long running task
isRefreshing = true isRefreshing = true

View file

@ -16,10 +16,11 @@ material3-core = { module = "androidx.compose.material3:material3" }
material-icons = { module = "androidx.compose.material:material-icons-extended" } material-icons = { module = "androidx.compose.material:material-icons-extended" }
# Here until M3's swipeable became public https://issuetracker.google.com/issues/234640556 # Here until M3's swipeable became public https://issuetracker.google.com/issues/234640556
material-core = { module = "androidx.compose.material:material" } # Using alpha version for PullRefresh fix
# TODO: use default version after next Compose BOM is released
material-core = { module = "androidx.compose.material:material", version = "1.4.0-alpha03" }
accompanist-webview = { module = "com.google.accompanist:accompanist-webview", version.ref = "accompanist" } accompanist-webview = { module = "com.google.accompanist:accompanist-webview", version.ref = "accompanist" }
accompanist-swiperefresh = { module = "com.google.accompanist:accompanist-swiperefresh", version.ref = "accompanist" }
accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" } accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" }
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" } accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
accompanist-themeadapter = { module = "com.google.accompanist:accompanist-themeadapter-material3", version.ref = "accompanist" } accompanist-themeadapter = { module = "com.google.accompanist:accompanist-themeadapter-material3", version.ref = "accompanist" }