mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Migrate Accompanist SwipeRefresh to Compose PullRefresh (#8106)
This commit is contained in:
		@@ -179,7 +179,6 @@ dependencies {
 | 
			
		||||
    implementation(compose.ui.tooling)
 | 
			
		||||
    implementation(compose.ui.util)
 | 
			
		||||
    implementation(compose.accompanist.webview)
 | 
			
		||||
    implementation(compose.accompanist.swiperefresh)
 | 
			
		||||
    implementation(compose.accompanist.flowlayout)
 | 
			
		||||
    implementation(compose.accompanist.permissions)
 | 
			
		||||
    implementation(compose.accompanist.themeadapter)
 | 
			
		||||
@@ -325,6 +324,7 @@ tasks {
 | 
			
		||||
            "-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
 | 
			
		||||
            "-opt-in=androidx.compose.material.ExperimentalMaterialApi",
 | 
			
		||||
            "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
 | 
			
		||||
            "-opt-in=androidx.compose.material.ExperimentalMaterialApi",
 | 
			
		||||
            "-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
 | 
			
		||||
            "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
 | 
			
		||||
            "-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ 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.SwipeRefresh
 | 
			
		||||
import eu.kanade.presentation.components.PullRefresh
 | 
			
		||||
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
 | 
			
		||||
import eu.kanade.presentation.theme.header
 | 
			
		||||
import eu.kanade.presentation.util.padding
 | 
			
		||||
@@ -68,7 +68,7 @@ fun ExtensionScreen(
 | 
			
		||||
    onClickUpdateAll: () -> Unit,
 | 
			
		||||
    onRefresh: () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    SwipeRefresh(
 | 
			
		||||
    PullRefresh(
 | 
			
		||||
        refreshing = state.isRefreshing,
 | 
			
		||||
        onRefresh = onRefresh,
 | 
			
		||||
        enabled = !state.isLoading,
 | 
			
		||||
 
 | 
			
		||||
@@ -309,7 +309,7 @@ private fun Modifier.selectedOutline(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return this then modifierElementOf(
 | 
			
		||||
        params = isSelected.hashCode() + color.hashCode(),
 | 
			
		||||
        key = isSelected.hashCode() + color.hashCode(),
 | 
			
		||||
        create = { SelectedOutlineNode(isSelected, color) },
 | 
			
		||||
        update = {
 | 
			
		||||
            it.selected = isSelected
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +18,7 @@ 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.SwipeRefresh
 | 
			
		||||
import eu.kanade.presentation.components.PullRefresh
 | 
			
		||||
import eu.kanade.presentation.components.rememberPagerState
 | 
			
		||||
import eu.kanade.tachiyomi.ui.library.LibraryItem
 | 
			
		||||
import kotlinx.coroutines.delay
 | 
			
		||||
@@ -79,11 +79,11 @@ fun LibraryContent(
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SwipeRefresh(
 | 
			
		||||
        PullRefresh(
 | 
			
		||||
            refreshing = isRefreshing,
 | 
			
		||||
            onRefresh = {
 | 
			
		||||
                val started = onRefresh(categories[currentPage()])
 | 
			
		||||
                if (!started) return@SwipeRefresh
 | 
			
		||||
                if (!started) return@PullRefresh
 | 
			
		||||
                scope.launch {
 | 
			
		||||
                    // Fake refresh status but hide it after a second as it's a long running task
 | 
			
		||||
                    isRefreshing = true
 | 
			
		||||
 
 | 
			
		||||
@@ -51,8 +51,8 @@ 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.PullRefresh
 | 
			
		||||
import eu.kanade.presentation.components.Scaffold
 | 
			
		||||
import eu.kanade.presentation.components.SwipeRefresh
 | 
			
		||||
import eu.kanade.presentation.components.TwoPanelBox
 | 
			
		||||
import eu.kanade.presentation.components.VerticalFastScroller
 | 
			
		||||
import eu.kanade.presentation.manga.components.ChapterHeader
 | 
			
		||||
@@ -287,7 +287,7 @@ private fun MangaScreenSmallImpl(
 | 
			
		||||
    ) { contentPadding ->
 | 
			
		||||
        val topPadding = contentPadding.calculateTopPadding()
 | 
			
		||||
 | 
			
		||||
        SwipeRefresh(
 | 
			
		||||
        PullRefresh(
 | 
			
		||||
            refreshing = state.isRefreshingData,
 | 
			
		||||
            onRefresh = onRefresh,
 | 
			
		||||
            enabled = chapters.fastAll { !it.selected },
 | 
			
		||||
@@ -421,7 +421,7 @@ fun MangaScreenLargeImpl(
 | 
			
		||||
 | 
			
		||||
    val insetPadding = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal).asPaddingValues()
 | 
			
		||||
    var topBarHeight by remember { mutableStateOf(0) }
 | 
			
		||||
    SwipeRefresh(
 | 
			
		||||
    PullRefresh(
 | 
			
		||||
        refreshing = state.isRefreshingData,
 | 
			
		||||
        onRefresh = onRefresh,
 | 
			
		||||
        enabled = chapters.fastAll { !it.selected },
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,8 @@ import eu.kanade.presentation.components.EmptyScreen
 | 
			
		||||
import eu.kanade.presentation.components.FastScrollLazyColumn
 | 
			
		||||
import eu.kanade.presentation.components.LoadingScreen
 | 
			
		||||
import eu.kanade.presentation.components.MangaBottomActionMenu
 | 
			
		||||
import eu.kanade.presentation.components.PullRefresh
 | 
			
		||||
import eu.kanade.presentation.components.Scaffold
 | 
			
		||||
import eu.kanade.presentation.components.SwipeRefresh
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.model.Download
 | 
			
		||||
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
 | 
			
		||||
@@ -96,11 +96,11 @@ fun UpdateScreen(
 | 
			
		||||
                val scope = rememberCoroutineScope()
 | 
			
		||||
                var isRefreshing by remember { mutableStateOf(false) }
 | 
			
		||||
 | 
			
		||||
                SwipeRefresh(
 | 
			
		||||
                PullRefresh(
 | 
			
		||||
                    refreshing = isRefreshing,
 | 
			
		||||
                    onRefresh = {
 | 
			
		||||
                        val started = onUpdateLibrary()
 | 
			
		||||
                        if (!started) return@SwipeRefresh
 | 
			
		||||
                        if (!started) return@PullRefresh
 | 
			
		||||
                        scope.launch {
 | 
			
		||||
                            // Fake refresh status but hide it after a second as it's a long running task
 | 
			
		||||
                            isRefreshing = true
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,11 @@ material3-core = { module = "androidx.compose.material3:material3" }
 | 
			
		||||
material-icons = { module = "androidx.compose.material:material-icons-extended" }
 | 
			
		||||
 | 
			
		||||
# 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-swiperefresh = { module = "com.google.accompanist:accompanist-swiperefresh", 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-themeadapter = { module = "com.google.accompanist:accompanist-themeadapter-material3", version.ref = "accompanist" }
 | 
			
		||||
		Reference in New Issue
	
	Block a user