Parcourir la source

Migrate Accompanist SwipeRefresh to Compose PullRefresh (#8106)

stevenyomi il y a 2 ans
Parent
commit
2c4ddca38e

+ 1 - 1
app/build.gradle.kts

@@ -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",

+ 2 - 2
app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt

@@ -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,

+ 1 - 1
app/src/main/java/eu/kanade/presentation/components/CommonMangaItem.kt

@@ -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

+ 50 - 0
app/src/main/java/eu/kanade/presentation/components/PullRefresh.kt

@@ -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,
+            )
+        }
+    }
+}

+ 0 - 44
app/src/main/java/eu/kanade/presentation/components/SwipeRefresh.kt

@@ -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()
-    }
-}

+ 3 - 3
app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt

@@ -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

+ 3 - 3
app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt

@@ -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 },

+ 3 - 3
app/src/main/java/eu/kanade/presentation/updates/UpdatesScreen.kt

@@ -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

+ 3 - 2
gradle/compose.versions.toml

@@ -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" }