mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-18 03:17:03 +05:30
Merge #151
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:
commit
2a543d3aad
9 changed files with 43 additions and 139 deletions
|
@ -55,6 +55,7 @@ dependencies {
|
||||||
implementation(Dependencies.ThirdParty.accompanist)
|
implementation(Dependencies.ThirdParty.accompanist)
|
||||||
implementation(Dependencies.ThirdParty.composeFlowLayout)
|
implementation(Dependencies.ThirdParty.composeFlowLayout)
|
||||||
implementation(Dependencies.ThirdParty.Moshi.lib)
|
implementation(Dependencies.ThirdParty.Moshi.lib)
|
||||||
|
implementation(Dependencies.ThirdParty.pullToRefresh)
|
||||||
implementation(Dependencies.ThirdParty.Retrofit.moshi)
|
implementation(Dependencies.ThirdParty.Retrofit.moshi)
|
||||||
implementation(Dependencies.ThirdParty.SQLDelight.androidDriver)
|
implementation(Dependencies.ThirdParty.SQLDelight.androidDriver)
|
||||||
testImplementation(Dependencies.Testing.junit)
|
testImplementation(Dependencies.Testing.junit)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.1 KiB |
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,11 @@
|
||||||
package dev.msfjarvis.lobsters.ui.main
|
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.layout.padding
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.BottomNavigation
|
import androidx.compose.material.BottomNavigation
|
||||||
import androidx.compose.material.BottomNavigationItem
|
import androidx.compose.material.BottomNavigationItem
|
||||||
import androidx.compose.material.Scaffold
|
import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
@ -16,7 +13,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.compose.KEY_ROUTE
|
import androidx.navigation.compose.KEY_ROUTE
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
|
@ -25,7 +21,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.navigate
|
import androidx.navigation.compose.navigate
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import dev.msfjarvis.lobsters.R
|
|
||||||
import dev.msfjarvis.lobsters.ui.navigation.Destination
|
import dev.msfjarvis.lobsters.ui.navigation.Destination
|
||||||
import dev.msfjarvis.lobsters.ui.posts.HottestPosts
|
import dev.msfjarvis.lobsters.ui.posts.HottestPosts
|
||||||
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
|
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
|
||||||
|
@ -56,12 +51,6 @@ fun LobstersApp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
|
||||||
LobstersTopBar(
|
|
||||||
currentDestination = currentDestination,
|
|
||||||
reloadPosts = { viewModel.reloadPosts() },
|
|
||||||
)
|
|
||||||
},
|
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
LobstersBottomNav(
|
LobstersBottomNav(
|
||||||
currentDestination,
|
currentDestination,
|
||||||
|
@ -75,9 +64,10 @@ fun LobstersApp() {
|
||||||
HottestPosts(
|
HottestPosts(
|
||||||
posts = hottestPosts,
|
posts = hottestPosts,
|
||||||
listState = hottestPostsListState,
|
listState = hottestPostsListState,
|
||||||
|
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
|
||||||
isPostSaved = viewModel::isPostSaved,
|
isPostSaved = viewModel::isPostSaved,
|
||||||
saveAction = viewModel::toggleSave,
|
saveAction = viewModel::toggleSave,
|
||||||
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
|
refreshAction = viewModel::reloadPosts,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable(Destination.Saved.route) {
|
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
|
@Composable
|
||||||
fun LobstersBottomNav(
|
fun LobstersBottomNav(
|
||||||
currentDestination: Destination,
|
currentDestination: Destination,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import androidx.paging.compose.items
|
import androidx.paging.compose.items
|
||||||
|
import com.puculek.pulltorefresh.PullToRefresh
|
||||||
import dev.msfjarvis.lobsters.data.local.SavedPost
|
import dev.msfjarvis.lobsters.data.local.SavedPost
|
||||||
import dev.msfjarvis.lobsters.model.LobstersPost
|
import dev.msfjarvis.lobsters.model.LobstersPost
|
||||||
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
|
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
|
||||||
|
@ -20,12 +21,23 @@ import dev.msfjarvis.lobsters.util.toDbModel
|
||||||
fun HottestPosts(
|
fun HottestPosts(
|
||||||
posts: LazyPagingItems<LobstersPost>,
|
posts: LazyPagingItems<LobstersPost>,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
isPostSaved: (String) -> Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
isPostSaved: (String) -> Boolean,
|
||||||
saveAction: (SavedPost) -> Unit,
|
saveAction: (SavedPost) -> Unit,
|
||||||
|
refreshAction: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val urlLauncher = LocalUrlLauncher.current
|
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) {
|
if (posts.loadState.refresh == LoadState.Loading) {
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
items(15) {
|
items(15) {
|
||||||
|
@ -58,3 +70,4 @@ fun HottestPosts(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ object Dependencies {
|
||||||
|
|
||||||
const val accompanist = "dev.chrisbanes.accompanist:accompanist-coil:0.6.2"
|
const val accompanist = "dev.chrisbanes.accompanist:accompanist-coil:0.6.2"
|
||||||
const val composeFlowLayout = "com.star-zero:compose-flowlayout:0.0.1"
|
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 {
|
object Moshi {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue