Refactor SwipeRefresh and fix some issues (#8169)
This commit is contained in:
parent
737d0fb8f3
commit
404f53b16b
@ -37,14 +37,12 @@ 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.FlowRow
|
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.BaseBrowseItem
|
||||||
import eu.kanade.presentation.browse.components.ExtensionIcon
|
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.SwipeRefreshIndicator
|
import eu.kanade.presentation.components.SwipeRefresh
|
||||||
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.horizontalPadding
|
import eu.kanade.presentation.util.horizontalPadding
|
||||||
@ -73,9 +71,9 @@ fun ExtensionScreen(
|
|||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(presenter.isRefreshing),
|
refreshing = presenter.isRefreshing,
|
||||||
indicator = { s, trigger -> SwipeRefreshIndicator(s, trigger) },
|
|
||||||
onRefresh = onRefresh,
|
onRefresh = onRefresh,
|
||||||
|
enabled = !presenter.isLoading,
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
presenter.isLoading -> LoadingScreen()
|
presenter.isLoading -> LoadingScreen()
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
package eu.kanade.presentation.components
|
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.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
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 com.google.accompanist.swiperefresh.SwipeRefreshState
|
import com.google.accompanist.swiperefresh.SwipeRefreshState
|
||||||
|
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
||||||
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator as AccompanistSwipeRefreshIndicator
|
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator as AccompanistSwipeRefreshIndicator
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -21,3 +26,30 @@ fun SwipeRefreshIndicator(
|
|||||||
refreshingOffset = refreshingOffset,
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,14 +17,12 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
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.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.EmptyScreen
|
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.presentation.library.LibraryState
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
import eu.kanade.tachiyomi.ui.library.LibraryItem
|
||||||
@ -89,7 +87,7 @@ fun LibraryContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(isRefreshing = isRefreshing),
|
refreshing = isRefreshing,
|
||||||
onRefresh = {
|
onRefresh = {
|
||||||
val started = onRefresh(categories[currentPage()])
|
val started = onRefresh(categories[currentPage()])
|
||||||
if (!started) return@SwipeRefresh
|
if (!started) return@SwipeRefresh
|
||||||
@ -100,12 +98,7 @@ fun LibraryContent(
|
|||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
indicator = { s, trigger ->
|
enabled = state.selectionMode.not(),
|
||||||
SwipeRefreshIndicator(
|
|
||||||
state = s,
|
|
||||||
refreshTriggerDistance = trigger,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty) {
|
if (state.searchQuery.isNullOrEmpty() && isLibraryEmpty) {
|
||||||
val handler = LocalUriHandler.current
|
val handler = LocalUriHandler.current
|
||||||
|
@ -48,15 +48,13 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
|||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
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.domain.chapter.model.Chapter
|
||||||
import eu.kanade.presentation.components.ChapterDownloadAction
|
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.Scaffold
|
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.components.VerticalFastScroller
|
||||||
import eu.kanade.presentation.manga.components.ChapterHeader
|
import eu.kanade.presentation.manga.components.ChapterHeader
|
||||||
import eu.kanade.presentation.manga.components.ExpandableMangaDescription
|
import eu.kanade.presentation.manga.components.ExpandableMangaDescription
|
||||||
@ -290,16 +288,10 @@ private fun MangaScreenSmallImpl(
|
|||||||
val topPadding = contentPadding.calculateTopPadding()
|
val topPadding = contentPadding.calculateTopPadding()
|
||||||
|
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(state.isRefreshingData),
|
refreshing = state.isRefreshingData,
|
||||||
onRefresh = onRefresh,
|
onRefresh = onRefresh,
|
||||||
swipeEnabled = !chapters.any { it.selected },
|
enabled = chapters.none { it.selected },
|
||||||
indicatorPadding = contentPadding,
|
indicatorPadding = contentPadding,
|
||||||
indicator = { s, trigger ->
|
|
||||||
SwipeRefreshIndicator(
|
|
||||||
state = s,
|
|
||||||
refreshTriggerDistance = trigger,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
VerticalFastScroller(
|
VerticalFastScroller(
|
||||||
listState = chapterListState,
|
listState = chapterListState,
|
||||||
@ -425,21 +417,14 @@ fun MangaScreenLargeImpl(
|
|||||||
val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues()
|
val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues()
|
||||||
val (topBarHeight, onTopBarHeightChanged) = remember { mutableStateOf(0) }
|
val (topBarHeight, onTopBarHeightChanged) = remember { mutableStateOf(0) }
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(state.isRefreshingData),
|
refreshing = state.isRefreshingData,
|
||||||
onRefresh = onRefresh,
|
onRefresh = onRefresh,
|
||||||
swipeEnabled = !chapters.any { it.selected },
|
enabled = chapters.none { it.selected },
|
||||||
indicatorPadding = PaddingValues(
|
indicatorPadding = PaddingValues(
|
||||||
start = insetPadding.calculateStartPadding(layoutDirection),
|
start = insetPadding.calculateStartPadding(layoutDirection),
|
||||||
top = with(density) { topBarHeight.toDp() },
|
top = with(density) { topBarHeight.toDp() },
|
||||||
end = insetPadding.calculateEndPadding(layoutDirection),
|
end = insetPadding.calculateEndPadding(layoutDirection),
|
||||||
),
|
),
|
||||||
clipIndicatorToPadding = true,
|
|
||||||
indicator = { s, trigger ->
|
|
||||||
SwipeRefreshIndicator(
|
|
||||||
state = s,
|
|
||||||
refreshTriggerDistance = trigger,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
val chapterListState = rememberLazyListState()
|
val chapterListState = rememberLazyListState()
|
||||||
|
|
||||||
|
@ -24,8 +24,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.res.stringResource
|
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.AppBar
|
||||||
import eu.kanade.presentation.components.ChapterDownloadAction
|
import eu.kanade.presentation.components.ChapterDownloadAction
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
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.LoadingScreen
|
||||||
import eu.kanade.presentation.components.MangaBottomActionMenu
|
import eu.kanade.presentation.components.MangaBottomActionMenu
|
||||||
import eu.kanade.presentation.components.Scaffold
|
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.components.VerticalFastScroller
|
||||||
import eu.kanade.presentation.util.plus
|
import eu.kanade.presentation.util.plus
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -130,7 +128,7 @@ private fun UpdateScreenContent(
|
|||||||
var isRefreshing by remember { mutableStateOf(false) }
|
var isRefreshing by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
state = rememberSwipeRefreshState(isRefreshing = isRefreshing),
|
refreshing = isRefreshing,
|
||||||
onRefresh = {
|
onRefresh = {
|
||||||
val started = onUpdateLibrary()
|
val started = onUpdateLibrary()
|
||||||
if (!started) return@SwipeRefresh
|
if (!started) return@SwipeRefresh
|
||||||
@ -141,14 +139,8 @@ private fun UpdateScreenContent(
|
|||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
swipeEnabled = presenter.selectionMode.not(),
|
enabled = presenter.selectionMode.not(),
|
||||||
indicatorPadding = contentPaddingWithNavBar,
|
indicatorPadding = contentPaddingWithNavBar,
|
||||||
indicator = { s, trigger ->
|
|
||||||
SwipeRefreshIndicator(
|
|
||||||
state = s,
|
|
||||||
refreshTriggerDistance = trigger,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
if (presenter.uiModels.isEmpty()) {
|
if (presenter.uiModels.isEmpty()) {
|
||||||
EmptyScreen(textResource = R.string.information_no_recent)
|
EmptyScreen(textResource = R.string.information_no_recent)
|
||||||
|
Loading…
Reference in New Issue
Block a user