151: Use pull-to-refresh for reloading r=msfjarvis a=msfjarvis

bors r+

Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
bors[bot] 2021-03-12 21:16:22 +00:00 committed by GitHub
commit 2a543d3aad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 43 additions and 139 deletions

View file

@ -55,6 +55,7 @@ dependencies {
implementation(Dependencies.ThirdParty.accompanist)
implementation(Dependencies.ThirdParty.composeFlowLayout)
implementation(Dependencies.ThirdParty.Moshi.lib)
implementation(Dependencies.ThirdParty.pullToRefresh)
implementation(Dependencies.ThirdParty.Retrofit.moshi)
implementation(Dependencies.ThirdParty.SQLDelight.androidDriver)
testImplementation(Dependencies.Testing.junit)

View file

@ -1,74 +0,0 @@
package dev.msfjarvis.lobsters.ui.main
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onRoot
import com.karumi.shot.ScreenshotTest
import dev.msfjarvis.lobsters.ui.DarkTestTheme
import dev.msfjarvis.lobsters.ui.LightTestTheme
import dev.msfjarvis.lobsters.ui.navigation.Destination
import org.junit.Rule
import org.junit.Test
class LobstersTopBarTest : ScreenshotTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun showsRefreshIconWhenOnHottestPostsScreen_DarkTheme() {
composeTestRule.setContent {
DarkTestTheme {
LobstersTopBar(
currentDestination = Destination.Hottest,
reloadPosts = { /*TODO*/ }
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
@Test
fun showsRefreshIconWhenOnHottestPostsScreen_LightTheme() {
composeTestRule.setContent {
LightTestTheme {
LobstersTopBar(
currentDestination = Destination.Hottest,
reloadPosts = { /*TODO*/ }
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
@Test
fun doesNotShowRefreshIconWhenOnSavedPostsScreen_DarkTheme() {
composeTestRule.setContent {
DarkTestTheme {
LobstersTopBar(
currentDestination = Destination.Saved,
reloadPosts = { /*TODO*/ }
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
@Test
fun doesNotShowRefreshIconWhenOnSavedPostsScreen_LightTheme() {
composeTestRule.setContent {
LightTestTheme {
LobstersTopBar(
currentDestination = Destination.Saved,
reloadPosts = { /*TODO*/ }
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
}

View file

@ -1,14 +1,11 @@
package dev.msfjarvis.lobsters.ui.main
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@ -16,7 +13,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.KEY_ROUTE
import androidx.navigation.compose.NavHost
@ -25,7 +21,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.navigate
import androidx.navigation.compose.rememberNavController
import androidx.paging.compose.collectAsLazyPagingItems
import dev.msfjarvis.lobsters.R
import dev.msfjarvis.lobsters.ui.navigation.Destination
import dev.msfjarvis.lobsters.ui.posts.HottestPosts
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
@ -56,12 +51,6 @@ fun LobstersApp() {
}
Scaffold(
topBar = {
LobstersTopBar(
currentDestination = currentDestination,
reloadPosts = { viewModel.reloadPosts() },
)
},
bottomBar = {
LobstersBottomNav(
currentDestination,
@ -75,9 +64,10 @@ fun LobstersApp() {
HottestPosts(
posts = hottestPosts,
listState = hottestPostsListState,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
isPostSaved = viewModel::isPostSaved,
saveAction = viewModel::toggleSave,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
refreshAction = viewModel::reloadPosts,
)
}
composable(Destination.Saved.route) {
@ -91,33 +81,6 @@ fun LobstersApp() {
}
}
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun LobstersTopBar(
currentDestination: Destination,
reloadPosts: () -> Unit,
) {
TopAppBar(
title = {
Text(
text = stringResource(id = R.string.app_name),
modifier = Modifier.padding(vertical = 8.dp),
)
},
actions = {
if (currentDestination == Destination.Hottest) {
IconResource(
resourceId = R.drawable.ic_refresh_24px,
contentDescription = stringResource(id = R.string.refresh_posts_content_description),
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 8.dp)
.clickable { reloadPosts() },
)
}
}
)
}
@Composable
fun LobstersBottomNav(
currentDestination: Destination,

View file

@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.items
import com.puculek.pulltorefresh.PullToRefresh
import dev.msfjarvis.lobsters.data.local.SavedPost
import dev.msfjarvis.lobsters.model.LobstersPost
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
@ -20,12 +21,23 @@ import dev.msfjarvis.lobsters.util.toDbModel
fun HottestPosts(
posts: LazyPagingItems<LobstersPost>,
listState: LazyListState,
isPostSaved: (String) -> Boolean,
modifier: Modifier = Modifier,
isPostSaved: (String) -> Boolean,
saveAction: (SavedPost) -> Unit,
refreshAction: () -> Unit,
) {
val urlLauncher = LocalUrlLauncher.current
var isRefreshing by mutableStateOf(false)
PullToRefresh(
isRefreshing = isRefreshing,
onRefresh = {
if (posts.loadState.refresh != LoadState.Loading) {
isRefreshing = isRefreshing.not()
refreshAction()
}
},
) {
if (posts.loadState.refresh == LoadState.Loading) {
LazyColumn {
items(15) {
@ -57,4 +69,5 @@ fun HottestPosts(
}
}
}
}
}

View file

@ -67,6 +67,7 @@ object Dependencies {
const val accompanist = "dev.chrisbanes.accompanist:accompanist-coil:0.6.2"
const val composeFlowLayout = "com.star-zero:compose-flowlayout:0.0.1"
const val pullToRefresh = "com.puculek.pulltorefresh:pull-to-refresh-compose:1.0.0"
object Moshi {