fix(android): migrate to Material3 pull refresh indicator

This commit is contained in:
Harsh Shandilya 2024-08-28 13:25:41 +05:30
parent 8651a4f66b
commit 4f3bafc051
3 changed files with 21 additions and 22 deletions

View file

@ -100,7 +100,6 @@ dependencies {
implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json) implementation(libs.kotlinx.serialization.json)
implementation(libs.material3.pulltorefresh)
implementation(libs.napier) implementation(libs.napier)
implementation(libs.okhttp.core) implementation(libs.okhttp.core)
implementation(libs.okhttp.loggingInterceptor) implementation(libs.okhttp.loggingInterceptor)

View file

@ -7,7 +7,6 @@
package dev.msfjarvis.claw.android.ui.lists package dev.msfjarvis.claw.android.ui.lists
import androidx.activity.compose.ReportDrawnWhen import androidx.activity.compose.ReportDrawnWhen
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -17,10 +16,12 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -38,9 +39,6 @@ import dev.msfjarvis.claw.common.ui.NetworkError
import dev.msfjarvis.claw.common.ui.ProgressBar import dev.msfjarvis.claw.common.ui.ProgressBar
import dev.msfjarvis.claw.common.ui.preview.DevicePreviews import dev.msfjarvis.claw.common.ui.preview.DevicePreviews
import dev.msfjarvis.claw.model.UIPost import dev.msfjarvis.claw.model.UIPost
import eu.bambooapps.material3.pullrefresh.PullRefreshIndicator
import eu.bambooapps.material3.pullrefresh.pullRefresh
import eu.bambooapps.material3.pullrefresh.rememberPullRefreshState
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@ -52,16 +50,25 @@ fun NetworkPosts(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
ReportDrawnWhen { lazyPagingItems.itemCount > 0 } ReportDrawnWhen { lazyPagingItems.itemCount > 0 }
val isRefreshing by val refreshLoadState by rememberUpdatedState(lazyPagingItems.loadState.refresh)
remember(lazyPagingItems) { val state = rememberPullToRefreshState()
derivedStateOf { lazyPagingItems.loadState.refresh == LoadState.Loading } PullToRefreshBox(
} modifier = modifier.fillMaxSize(),
val pullRefreshState = rememberPullRefreshState(isRefreshing, lazyPagingItems::refresh) isRefreshing = refreshLoadState == LoadState.Loading,
Box(modifier = modifier.fillMaxSize().pullRefresh(pullRefreshState)) { state = state,
if (lazyPagingItems.itemCount == 0 && lazyPagingItems.loadState.refresh is LoadState.Error) { onRefresh = { lazyPagingItems.refresh() },
indicator = {
PullToRefreshDefaults.Indicator(
state = state,
isRefreshing = refreshLoadState == LoadState.Loading,
modifier = Modifier.align(Alignment.TopCenter),
)
},
) {
if (lazyPagingItems.itemCount == 0 && refreshLoadState is LoadState.Error) {
NetworkError( NetworkError(
label = "Failed to load posts", label = "Failed to load posts",
error = (lazyPagingItems.loadState.refresh as LoadState.Error).error, error = (refreshLoadState as LoadState.Error).error,
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
) )
} else { } else {
@ -89,12 +96,6 @@ fun NetworkPosts(
} }
} }
} }
PullRefreshIndicator(
refreshing = isRefreshing,
state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter),
shadowElevation = 6.dp, // From M2 implementation
)
} }
} }

View file

@ -90,7 +90,6 @@ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-t
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
leakcanary-android-test = { module = "com.squareup.leakcanary:leakcanary-android-test", version.ref = "leakcanary" } leakcanary-android-test = { module = "com.squareup.leakcanary:leakcanary-android-test", version.ref = "leakcanary" }
material3-pulltorefresh = "eu.bambooapps:compose-material3-pullrefresh:1.1.1"
napier = "io.github.aakira:napier:2.7.1" napier = "io.github.aakira:napier:2.7.1"
okhttp-bom = "com.squareup.okhttp3:okhttp-bom:4.12.0" okhttp-bom = "com.squareup.okhttp3:okhttp-bom:4.12.0"
okhttp-core = { module = "com.squareup.okhttp3:okhttp" } okhttp-core = { module = "com.squareup.okhttp3:okhttp" }