From 404f53b16b59b3882069c5c8f3b20890a85ccd0d Mon Sep 17 00:00:00 2001 From: stevenyomi <95685115+stevenyomi@users.noreply.github.com> Date: Sun, 9 Oct 2022 23:20:43 +0800 Subject: [PATCH] Refactor SwipeRefresh and fix some issues (#8169) --- .../presentation/browse/ExtensionsScreen.kt | 8 ++--- .../presentation/components/SwipeRefresh.kt | 32 +++++++++++++++++++ .../library/components/LibraryContent.kt | 13 ++------ .../kanade/presentation/manga/MangaScreen.kt | 25 +++------------ .../presentation/updates/UpdatesScreen.kt | 14 ++------ 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt index 9c363eb8ff..56cc104ac6 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt @@ -37,14 +37,12 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.google.accompanist.flowlayout.FlowRow -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import eu.kanade.presentation.browse.components.BaseBrowseItem import eu.kanade.presentation.browse.components.ExtensionIcon import eu.kanade.presentation.components.EmptyScreen import eu.kanade.presentation.components.FastScrollLazyColumn import eu.kanade.presentation.components.LoadingScreen -import eu.kanade.presentation.components.SwipeRefreshIndicator +import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText import eu.kanade.presentation.theme.header import eu.kanade.presentation.util.horizontalPadding @@ -73,9 +71,9 @@ fun ExtensionScreen( onRefresh: () -> Unit, ) { SwipeRefresh( - state = rememberSwipeRefreshState(presenter.isRefreshing), - indicator = { s, trigger -> SwipeRefreshIndicator(s, trigger) }, + refreshing = presenter.isRefreshing, onRefresh = onRefresh, + enabled = !presenter.isLoading, ) { when { presenter.isLoading -> LoadingScreen() diff --git a/app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt b/app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt index 6767835b63..daf765e2a6 100644 --- a/app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt +++ b/app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt @@ -1,10 +1,15 @@ package eu.kanade.presentation.components +import android.os.Build +import androidx.compose.foundation.LocalOverscrollConfiguration +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider 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 @@ -21,3 +26,30 @@ fun SwipeRefreshIndicator( 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) }, + ) { + // TODO: remove this workaround when A12 stretch overscroll works well with refreshing + // see https://github.com/tachiyomiorg/tachiyomi/issues/8168 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + CompositionLocalProvider(LocalOverscrollConfiguration provides null) { + content() + } + } else { + content() + } + } +} diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt index 6dce831f73..84477a5c38 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt @@ -17,14 +17,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalUriHandler import com.google.accompanist.pager.rememberPagerState -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import eu.kanade.core.prefs.PreferenceMutableState import eu.kanade.domain.category.model.Category import eu.kanade.domain.library.model.LibraryDisplayMode import eu.kanade.domain.library.model.LibraryManga import eu.kanade.presentation.components.EmptyScreen -import eu.kanade.presentation.components.SwipeRefreshIndicator +import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.library.LibraryState import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.ui.library.LibraryItem @@ -89,7 +87,7 @@ fun LibraryContent( } SwipeRefresh( - state = rememberSwipeRefreshState(isRefreshing = isRefreshing), + refreshing = isRefreshing, onRefresh = { val started = onRefresh(categories[currentPage()]) if (!started) return@SwipeRefresh @@ -100,12 +98,7 @@ fun LibraryContent( isRefreshing = false } }, - indicator = { s, trigger -> - SwipeRefreshIndicator( - state = s, - refreshTriggerDistance = trigger, - ) - }, + enabled = state.selectionMode.not(), ) { if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty) { val handler = LocalUriHandler.current diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index 5177c63b81..e4d30c97ac 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -48,15 +48,13 @@ import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import eu.kanade.domain.chapter.model.Chapter import eu.kanade.presentation.components.ChapterDownloadAction import eu.kanade.presentation.components.ExtendedFloatingActionButton import eu.kanade.presentation.components.LazyColumn import eu.kanade.presentation.components.MangaBottomActionMenu import eu.kanade.presentation.components.Scaffold -import eu.kanade.presentation.components.SwipeRefreshIndicator +import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.components.VerticalFastScroller import eu.kanade.presentation.manga.components.ChapterHeader import eu.kanade.presentation.manga.components.ExpandableMangaDescription @@ -290,16 +288,10 @@ private fun MangaScreenSmallImpl( val topPadding = contentPadding.calculateTopPadding() SwipeRefresh( - state = rememberSwipeRefreshState(state.isRefreshingData), + refreshing = state.isRefreshingData, onRefresh = onRefresh, - swipeEnabled = !chapters.any { it.selected }, + enabled = chapters.none { it.selected }, indicatorPadding = contentPadding, - indicator = { s, trigger -> - SwipeRefreshIndicator( - state = s, - refreshTriggerDistance = trigger, - ) - }, ) { VerticalFastScroller( listState = chapterListState, @@ -425,21 +417,14 @@ fun MangaScreenLargeImpl( val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues() val (topBarHeight, onTopBarHeightChanged) = remember { mutableStateOf(0) } SwipeRefresh( - state = rememberSwipeRefreshState(state.isRefreshingData), + refreshing = state.isRefreshingData, onRefresh = onRefresh, - swipeEnabled = !chapters.any { it.selected }, + enabled = chapters.none { it.selected }, indicatorPadding = PaddingValues( start = insetPadding.calculateStartPadding(layoutDirection), top = with(density) { topBarHeight.toDp() }, end = insetPadding.calculateEndPadding(layoutDirection), ), - clipIndicatorToPadding = true, - indicator = { s, trigger -> - SwipeRefreshIndicator( - state = s, - refreshTriggerDistance = trigger, - ) - }, ) { val chapterListState = rememberLazyListState() diff --git a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt index 650093f6ea..bb870ed89d 100644 --- a/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt @@ -24,8 +24,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource -import com.google.accompanist.swiperefresh.SwipeRefresh -import com.google.accompanist.swiperefresh.rememberSwipeRefreshState import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.ChapterDownloadAction import eu.kanade.presentation.components.EmptyScreen @@ -33,7 +31,7 @@ import eu.kanade.presentation.components.LazyColumn import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.MangaBottomActionMenu import eu.kanade.presentation.components.Scaffold -import eu.kanade.presentation.components.SwipeRefreshIndicator +import eu.kanade.presentation.components.SwipeRefresh import eu.kanade.presentation.components.VerticalFastScroller import eu.kanade.presentation.util.plus import eu.kanade.tachiyomi.R @@ -130,7 +128,7 @@ private fun UpdateScreenContent( var isRefreshing by remember { mutableStateOf(false) } SwipeRefresh( - state = rememberSwipeRefreshState(isRefreshing = isRefreshing), + refreshing = isRefreshing, onRefresh = { val started = onUpdateLibrary() if (!started) return@SwipeRefresh @@ -141,14 +139,8 @@ private fun UpdateScreenContent( isRefreshing = false } }, - swipeEnabled = presenter.selectionMode.not(), + enabled = presenter.selectionMode.not(), indicatorPadding = contentPaddingWithNavBar, - indicator = { s, trigger -> - SwipeRefreshIndicator( - state = s, - refreshTriggerDistance = trigger, - ) - }, ) { if (presenter.uiModels.isEmpty()) { EmptyScreen(textResource = R.string.information_no_recent)