Redesign and reimplementation for the empty BookmarksScreen along with two clarifying comments.

pull/443/head
Mohsen Rzna 3 years ago
parent fb5b70b9da
commit 0ab3aee941

@ -16,13 +16,16 @@
package com.google.samples.apps.nowinandroid.feature.bookmarks package com.google.samples.apps.nowinandroid.feature.bookmarks
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
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.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.layout.wrapContentSize
@ -30,17 +33,23 @@ import androidx.compose.foundation.lazy.grid.GridCells.Adaptive
import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
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.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank
import com.google.samples.apps.nowinandroid.core.ui.newsFeed import com.google.samples.apps.nowinandroid.core.ui.newsFeed
@ -59,7 +68,6 @@ internal fun BookmarksRoute(
) )
} }
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable @Composable
fun BookmarksScreen( fun BookmarksScreen(
feedState: NewsFeedUiState, feedState: NewsFeedUiState,
@ -68,6 +76,11 @@ fun BookmarksScreen(
) { ) {
val scrollableState = rememberLazyGridState() val scrollableState = rememberLazyGridState()
TrackScrollJank(scrollableState = scrollableState, stateName = "bookmarks:grid") TrackScrollJank(scrollableState = scrollableState, stateName = "bookmarks:grid")
/**
** The [LazyVerticalGrid] is handling the Loading and Success states when the feed is not empty.
**/
LazyVerticalGrid( LazyVerticalGrid(
columns = Adaptive(300.dp), columns = Adaptive(300.dp),
contentPadding = PaddingValues(16.dp), contentPadding = PaddingValues(16.dp),
@ -78,8 +91,8 @@ fun BookmarksScreen(
.fillMaxSize() .fillMaxSize()
.testTag("bookmarks:feed") .testTag("bookmarks:feed")
) { ) {
if (feedState is NewsFeedUiState.Loading) { when (feedState) {
item(span = { GridItemSpan(maxLineSpan) }) { is NewsFeedUiState.Loading -> item(span = { GridItemSpan(maxLineSpan) }) {
NiaLoadingWheel( NiaLoadingWheel(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -88,15 +101,74 @@ fun BookmarksScreen(
contentDesc = stringResource(id = R.string.saved_loading), contentDesc = stringResource(id = R.string.saved_loading),
) )
} }
is NewsFeedUiState.Success -> {
if (feedState.feed.isNotEmpty()) {
newsFeed(
feedState = feedState,
onNewsResourcesCheckedChanged = { id, _ -> removeFromBookmarks(id) },
)
item(span = { GridItemSpan(maxLineSpan) }) {
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
}
}
}
} }
}
/**
** The [Column] is handling the Empty state when the feed is empty.
**/
if (feedState is NewsFeedUiState.Success && feedState.feed.isEmpty()) {
OnEmptyStateView()
}
}
@Composable
private fun OnEmptyStateView() {
Column(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp)
.fillMaxSize()
.testTag("bookmarks:empty"),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
modifier = Modifier
.fillMaxWidth(),
painter = painterResource(id = R.drawable.img_no_bookmarks_error),
contentDescription = stringResource(id = R.string.bookmarks_empty_description),
)
Spacer(modifier = Modifier.height(16.dp))
newsFeed( Text(
feedState = feedState, text = stringResource(id = R.string.bookmarks_empty_error),
onNewsResourcesCheckedChanged = { id, _ -> removeFromBookmarks(id) }, textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth(),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
) )
item(span = { GridItemSpan(maxLineSpan) }) { Spacer(modifier = Modifier.height(5.dp))
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
} Text(
text = stringResource(id = R.string.bookmarks_empty_description),
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth(),
style = MaterialTheme.typography.bodyMedium
)
} }
} }
@DevicePreviews
@Composable
fun ShowErrorPreview() {
BookmarksScreen(
feedState = NewsFeedUiState.Success(emptyList()),
removeFromBookmarks = {},
modifier = Modifier
)
}
Loading…
Cancel
Save