diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/PullRefresh.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/PullRefresh.kt index b24baec43..9642cec71 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/PullRefresh.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/PullRefresh.kt @@ -47,22 +47,11 @@ fun PullRefresh( content: @Composable () -> Unit, ) { val state = rememberPullToRefreshState( - initialRefreshing = refreshing, + isRefreshing = refreshing, extraVerticalOffset = indicatorPadding.calculateTopPadding(), enabled = enabled, + onRefresh = onRefresh, ) - if (state.isRefreshing) { - LaunchedEffect(true) { - onRefresh() - } - } - LaunchedEffect(refreshing) { - if (refreshing && !state.isRefreshing) { - state.startRefreshAnimated() - } else if (!refreshing && state.isRefreshing) { - state.endRefreshAnimated() - } - } Box(modifier.nestedScroll(state.nestedScrollConnection)) { content() @@ -94,10 +83,11 @@ fun PullRefresh( @Composable private fun rememberPullToRefreshState( - initialRefreshing: Boolean, + isRefreshing: Boolean, extraVerticalOffset: Dp, positionalThreshold: Dp = 64.dp, enabled: () -> Boolean = { true }, + onRefresh: () -> Unit, ): PullToRefreshStateImpl { val density = LocalDensity.current val extraVerticalOffsetPx = with(density) { extraVerticalOffset.toPx() } @@ -106,18 +96,29 @@ private fun rememberPullToRefreshState( extraVerticalOffset, positionalThresholdPx, enabled, + onRefresh, saver = PullToRefreshStateImpl.Saver( extraVerticalOffset = extraVerticalOffsetPx, positionalThreshold = positionalThresholdPx, enabled = enabled, + onRefresh = onRefresh, ), ) { PullToRefreshStateImpl( - initialRefreshing = initialRefreshing, + initialRefreshing = isRefreshing, extraVerticalOffset = extraVerticalOffsetPx, positionalThreshold = positionalThresholdPx, enabled = enabled, + onRefresh = onRefresh, ) + }.also { + LaunchedEffect(isRefreshing) { + if (isRefreshing && !it.isRefreshing) { + it.startRefreshAnimated() + } else if (!isRefreshing && it.isRefreshing) { + it.endRefreshAnimated() + } + } } } @@ -128,6 +129,7 @@ private fun rememberPullToRefreshState( * @param extraVerticalOffset Extra vertical offset, in pixels, for the "refreshing" state * @param initialRefreshing The initial refreshing value of [PullToRefreshState] * @param enabled a callback used to determine whether scroll events are to be handled by this + * @param onRefresh a callback to run when pull-to-refresh action is triggered by user * [PullToRefreshState] */ private class PullToRefreshStateImpl( @@ -135,6 +137,7 @@ private class PullToRefreshStateImpl( private val extraVerticalOffset: Float, override val positionalThreshold: Float, enabled: () -> Boolean, + private val onRefresh: () -> Unit, ) : PullToRefreshState { override val progress get() = adjustedDistancePulled / positionalThreshold @@ -215,6 +218,7 @@ private class PullToRefreshStateImpl( if (isRefreshing) return 0f // Already refreshing, do nothing // Trigger refresh if (adjustedDistancePulled > positionalThreshold) { + onRefresh() startRefreshAnimated() } else { animateTo(0f) @@ -263,6 +267,7 @@ private class PullToRefreshStateImpl( extraVerticalOffset: Float, positionalThreshold: Float, enabled: () -> Boolean, + onRefresh: () -> Unit, ) = Saver( save = { it.isRefreshing }, restore = { isRefreshing -> @@ -271,6 +276,7 @@ private class PullToRefreshStateImpl( extraVerticalOffset = extraVerticalOffset, positionalThreshold = positionalThreshold, enabled = enabled, + onRefresh = onRefresh, ) }, )