Skip to content

Commit 2f9ffe0

Browse files
amjiaozachseidner1
andauthored
Add empty state (#52)
* Empty state + UI fixes * Address UI issues (#51) * Add missing border * Bump material version in preparation for pull to refresh * Fix border on home and past, fix carousel # Conflicts: # app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt # app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt * Address sport filter (issue #40) (#47) * Fix sport filter * Small readability fix * Empty state + UI fixes * Fix merging * small fix * PR Fixes * Small fixes * PR fixes --------- Co-authored-by: Zachary Seidner <58796478+zachseidner1@users.noreply.github.com>
1 parent deb9ff6 commit 2f9ffe0

4 files changed

Lines changed: 211 additions & 54 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.cornellappdev.score.components
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.height
9+
import androidx.compose.material3.Text
10+
import androidx.compose.runtime.Composable
11+
import androidx.compose.ui.Alignment
12+
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.res.painterResource
14+
import androidx.compose.ui.tooling.preview.Preview
15+
import androidx.compose.ui.unit.dp
16+
import com.cornellappdev.score.R
17+
import com.cornellappdev.score.theme.GrayMedium
18+
import com.cornellappdev.score.theme.GrayPrimary
19+
import com.cornellappdev.score.theme.Style.bodyNormal
20+
import com.cornellappdev.score.theme.Style.heading2
21+
22+
@Composable
23+
fun EmptyState(
24+
modifier: Modifier = Modifier
25+
) {
26+
Column(
27+
modifier = modifier,
28+
horizontalAlignment = Alignment.CenterHorizontally,
29+
verticalArrangement = Arrangement.Center
30+
) {
31+
Image(
32+
painter = painterResource(R.drawable.ic_speaker_gray),
33+
contentDescription = "score speaker icon"
34+
)
35+
Spacer(modifier = Modifier.height(16.dp))
36+
Text(
37+
text = "No games yet.",
38+
style = heading2.copy(color = GrayPrimary)
39+
)
40+
Spacer(modifier = Modifier.height(8.dp))
41+
Text(
42+
text = "Check back here later!",
43+
style = bodyNormal.copy(color = GrayMedium)
44+
)
45+
}
46+
}
47+
48+
@Preview
49+
@Composable
50+
private fun EmptyStatePreview() = ScorePreview {
51+
EmptyState()
52+
}

app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import androidx.compose.ui.res.painterResource
2424
import androidx.compose.ui.tooling.preview.Preview
2525
import androidx.compose.ui.unit.dp
2626
import androidx.hilt.navigation.compose.hiltViewModel
27+
import com.cornellappdev.score.components.EmptyState
2728
import com.cornellappdev.score.components.ErrorState
2829
import com.cornellappdev.score.components.GameCard
2930
import com.cornellappdev.score.components.GamesCarousel
@@ -101,21 +102,25 @@ private fun HomeLazyColumn(
101102
navigateToGameDetails: (String) -> Unit
102103
) {
103104
LazyColumn(contentPadding = PaddingValues(top = 24.dp)) {
104-
item {
105-
Text(
106-
text = "Latest",
107-
style = heading1,
108-
color = GrayPrimary,
109-
modifier = Modifier
110-
.fillMaxWidth()
111-
.padding(start = 24.dp)
112-
)
113-
}
114-
item {
115-
Spacer(Modifier.height(16.dp))
105+
if (uiState.filteredGames.isNotEmpty()) {
106+
item {
107+
Text(
108+
text = "Upcoming",
109+
style = heading1,
110+
color = GrayPrimary,
111+
modifier = Modifier
112+
.fillMaxWidth()
113+
.padding(start = 24.dp)
114+
)
115+
}
116+
item {
117+
Spacer(Modifier.height(16.dp))
118+
}
116119
}
117-
item {
118-
GamesCarousel(uiState.upcomingGames, navigateToGameDetails)
120+
if (uiState.filteredGames.isNotEmpty()) {
121+
item {
122+
GamesCarousel(uiState.upcomingGames, navigateToGameDetails)
123+
}
119124
}
120125
stickyHeader {
121126
Column(
@@ -146,24 +151,36 @@ private fun HomeLazyColumn(
146151
)
147152
}
148153
}
149-
item {
150-
Spacer(modifier = Modifier.height(24.dp))
151-
}
152-
items(uiState.filteredGames) {
153-
val game = it
154-
Column(modifier = Modifier.padding(horizontal = 24.dp)) {
155-
GameCard(
156-
teamLogo = game.teamLogo,
157-
team = game.team,
158-
date = game.dateString,
159-
isLive = game.isLive,
160-
genderIcon = painterResource(game.genderIcon),
161-
sportIcon = painterResource(game.sportIcon),
162-
location = game.location,
163-
topCornerRound = true,
164-
onClick = { navigateToGameDetails(game.id) }
165-
)
166-
Spacer(modifier = Modifier.height(16.dp))
154+
155+
if (uiState.filteredGames.isNotEmpty()) {
156+
item {
157+
Spacer(modifier = Modifier.height(24.dp))
158+
}
159+
items(uiState.filteredGames) {
160+
val game = it
161+
Column(modifier = Modifier.padding(horizontal = 24.dp)) {
162+
GameCard(
163+
teamLogo = game.teamLogo,
164+
team = game.team,
165+
date = game.dateString,
166+
isLive = game.isLive,
167+
genderIcon = painterResource(game.genderIcon),
168+
sportIcon = painterResource(game.sportIcon),
169+
location = game.location,
170+
topCornerRound = true,
171+
onClick = { navigateToGameDetails(game.id) }
172+
)
173+
Spacer(modifier = Modifier.height(16.dp))
174+
}
175+
}
176+
} else {
177+
item {
178+
Box(
179+
modifier = Modifier.fillMaxSize(),
180+
contentAlignment = Alignment.Center
181+
) {
182+
EmptyState()
183+
}
167184
}
168185
}
169186
}
@@ -191,3 +208,19 @@ private fun HomeScreenPreview() = ScorePreview {
191208
}
192209
}
193210

211+
@Preview
212+
@Composable
213+
private fun HomeScreenEmptyStatePreview() = ScorePreview {
214+
HomeContent(
215+
HomeUiState(
216+
selectedGender = GenderDivision.ALL,
217+
sportSelect = SportSelection.All,
218+
selectionList = sportSelectionList,
219+
loadedState = ApiResponse.Success(emptyList())
220+
),
221+
onGenderSelected = {},
222+
onSportSelected = {},
223+
onRefresh = {}
224+
)
225+
}
226+

app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box
77
import androidx.compose.foundation.layout.Column
88
import androidx.compose.foundation.layout.PaddingValues
99
import androidx.compose.foundation.layout.Spacer
10+
import androidx.compose.foundation.layout.fillMaxSize
1011
import androidx.compose.foundation.layout.fillMaxWidth
1112
import androidx.compose.foundation.layout.height
1213
import androidx.compose.foundation.layout.padding
@@ -21,6 +22,7 @@ import androidx.compose.ui.graphics.Color
2122
import androidx.compose.ui.tooling.preview.Preview
2223
import androidx.compose.ui.unit.dp
2324
import androidx.hilt.navigation.compose.hiltViewModel
25+
import com.cornellappdev.score.components.EmptyState
2426
import com.cornellappdev.score.components.ErrorState
2527
import com.cornellappdev.score.components.GamesCarousel
2628
import com.cornellappdev.score.components.LoadingScreen
@@ -98,21 +100,26 @@ private fun PastGamesLazyColumn(
98100
navigateToGameDetails: (String) -> Unit
99101
) {
100102
LazyColumn(contentPadding = PaddingValues(top = 24.dp)) {
101-
item {
102-
Text(
103-
text = "Latest",
104-
style = heading1,
105-
color = GrayPrimary,
106-
modifier = Modifier
107-
.fillMaxWidth()
108-
.padding(start = 24.dp)
109-
)
110-
}
111-
item {
112-
Spacer(Modifier.height(16.dp))
103+
if (uiState.filteredGames.isNotEmpty()) {
104+
item {
105+
Text(
106+
text = "Latest",
107+
style = heading1,
108+
color = GrayPrimary,
109+
modifier = Modifier
110+
.fillMaxWidth()
111+
.padding(start = 24.dp)
112+
)
113+
}
114+
item {
115+
Spacer(Modifier.height(16.dp))
116+
}
113117
}
114-
item {
115-
GamesCarousel(uiState.pastGames, navigateToGameDetails)
118+
119+
if (uiState.filteredGames.isNotEmpty()) {
120+
item {
121+
GamesCarousel(uiState.pastGames, navigateToGameDetails)
122+
}
116123
}
117124
stickyHeader {
118125
Column(
@@ -146,14 +153,25 @@ private fun PastGamesLazyColumn(
146153
item {
147154
Spacer(modifier = Modifier.height(24.dp))
148155
}
149-
items(uiState.filteredGames) {
150-
val game = it
151-
Column(modifier = Modifier.padding(horizontal = 24.dp)) {
152-
PastGameCard(
153-
data = game,
154-
onClick = { navigateToGameDetails(game.id) }
155-
)
156-
Spacer(modifier = Modifier.height(16.dp))
156+
if (uiState.filteredGames.isNotEmpty()) {
157+
items(uiState.filteredGames) {
158+
val game = it
159+
Column(modifier = Modifier.padding(horizontal = 24.dp)) {
160+
PastGameCard(
161+
data = game,
162+
onClick = { navigateToGameDetails(game.id) }
163+
)
164+
Spacer(modifier = Modifier.height(16.dp))
165+
}
166+
}
167+
} else{
168+
item{
169+
Box(
170+
modifier = Modifier.fillMaxSize(),
171+
contentAlignment = Alignment.Center
172+
) {
173+
EmptyState()
174+
}
157175
}
158176
}
159177
}
@@ -173,4 +191,20 @@ private fun PastGamesPreview() = ScorePreview {
173191
onSportSelected = {},
174192
onRefresh = {},
175193
)
194+
}
195+
196+
@Composable
197+
@Preview
198+
private fun PastGamesEmptyStatePreview() = ScorePreview {
199+
PastGamesContent(
200+
uiState = PastGamesUiState(
201+
selectedGender = GenderDivision.ALL,
202+
sportSelect = SportSelection.All,
203+
selectionList = sportSelectionList,
204+
loadedState = ApiResponse.Success(emptyList())
205+
),
206+
onGenderSelected = {},
207+
onSportSelected = {},
208+
onRefresh = {},
209+
)
176210
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="96dp"
3+
android:height="96dp"
4+
android:viewportWidth="96"
5+
android:viewportHeight="96">
6+
<group>
7+
<clip-path
8+
android:pathData="M0,0h96v96h-96z"/>
9+
<path
10+
android:pathData="M15.859,71.188C12.781,70.28 9.709,68.16 7.901,64.318C6.093,60.476 6.418,56.757 7.681,53.806C8.911,50.933 11.086,48.658 13.225,47.652L30.348,39.595C37.133,36.402 42.307,29.228 44.957,21.218C45.712,18.936 47.904,17.77 49.785,17.517C51.66,17.264 54.183,17.823 55.291,20.179L71.744,55.146C72.892,57.586 71.542,59.969 70.135,61.269C68.709,62.586 66.335,63.664 64.03,62.826C56.41,60.056 47.799,59.706 41.258,62.784L24.135,70.84C21.997,71.847 18.858,72.073 15.859,71.188ZM16.991,67.352C19.197,68.003 21.31,67.749 22.432,67.221L39.555,59.164C47.343,55.5 57.113,56.055 65.397,59.067C65.76,59.199 66.602,59.087 67.421,58.33C68.26,57.556 68.186,56.979 68.125,56.849L51.672,21.882C51.593,21.715 51.241,21.357 50.319,21.481C49.403,21.604 48.876,22.107 48.755,22.474C45.891,31.13 40.152,39.403 32.051,43.215L14.928,51.271C13.805,51.799 12.263,53.266 11.358,55.38C10.486,57.417 10.259,59.934 11.52,62.615C12.782,65.296 14.866,66.725 16.991,67.352Z"
11+
android:fillColor="#C2C2C2"
12+
android:fillType="evenOdd"/>
13+
<path
14+
android:pathData="M64.629,42.871C67.058,41.728 68.101,38.832 66.957,36.403C65.814,33.974 62.919,32.931 60.489,34.074L59.354,31.661C63.116,29.891 67.6,31.506 69.37,35.268C71.141,39.03 69.526,43.514 65.764,45.284L64.629,42.871Z"
15+
android:fillColor="#C2C2C2"
16+
android:fillType="evenOdd"/>
17+
<path
18+
android:pathData="M38.104,81.957L30.883,65.615L34.542,63.999L41.762,80.34C42.941,83.007 41.869,86.132 39.302,87.514C36.723,88.903 33.508,88.062 31.939,85.588L22.012,69.933L25.39,67.791L35.317,83.446C35.762,84.147 36.674,84.386 37.406,83.992C38.134,83.6 38.438,82.714 38.104,81.957Z"
19+
android:fillColor="#C2C2C2"
20+
android:fillType="evenOdd"/>
21+
<path
22+
android:pathData="M24.602,44.531L34.039,64.587L31.626,65.722L22.189,45.667L24.602,44.531Z"
23+
android:fillColor="#C2C2C2"
24+
android:fillType="evenOdd"/>
25+
<path
26+
android:pathData="M72.823,34.255C72.353,33.256 72.782,32.064 73.781,31.594L81.935,27.757C82.935,27.287 84.126,27.716 84.596,28.715C85.067,29.715 84.638,30.906 83.638,31.376L75.484,35.213C74.485,35.683 73.294,35.254 72.823,34.255Z"
27+
android:fillColor="#C2C2C2"
28+
android:fillType="evenOdd"/>
29+
<path
30+
android:pathData="M67.888,24.635C66.848,24.261 66.309,23.115 66.683,22.076L69.736,13.597C70.11,12.558 71.256,12.019 72.295,12.393C73.334,12.767 73.873,13.913 73.499,14.952L70.447,23.431C70.073,24.47 68.927,25.009 67.888,24.635Z"
31+
android:fillColor="#C2C2C2"
32+
android:fillType="evenOdd"/>
33+
<path
34+
android:pathData="M89.729,48.915C89.355,49.954 88.21,50.493 87.17,50.119L78.692,47.067C77.652,46.692 77.113,45.547 77.487,44.507C77.862,43.468 79.007,42.929 80.047,43.303L88.525,46.355C89.564,46.73 90.104,47.875 89.729,48.915Z"
35+
android:fillColor="#C2C2C2"
36+
android:fillType="evenOdd"/>
37+
</group>
38+
</vector>

0 commit comments

Comments
 (0)