Skip to content

Commit ecf9a70

Browse files
Emil jiang navigate (#73)
* initial commit * figma * pr comment address * Resolve merge conflicts * Fix empty state issues * Empty state on navigate --------- Co-authored-by: zachseidner1 <[email protected]>
1 parent 2f9ffe0 commit ecf9a70

9 files changed

Lines changed: 157 additions & 68 deletions

File tree

app/src/main/java/com/cornellappdev/score/components/EmptyState.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.cornellappdev.score.components
22

33
import androidx.compose.foundation.Image
44
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
56
import androidx.compose.foundation.layout.Column
67
import androidx.compose.foundation.layout.Spacer
78
import androidx.compose.foundation.layout.fillMaxWidth
@@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment
1213
import androidx.compose.ui.Modifier
1314
import androidx.compose.ui.res.painterResource
1415
import androidx.compose.ui.tooling.preview.Preview
16+
import androidx.compose.ui.unit.Dp
1517
import androidx.compose.ui.unit.dp
1618
import com.cornellappdev.score.R
1719
import com.cornellappdev.score.theme.GrayMedium
@@ -21,7 +23,9 @@ import com.cornellappdev.score.theme.Style.heading2
2123

2224
@Composable
2325
fun EmptyState(
24-
modifier: Modifier = Modifier
26+
modifier: Modifier = Modifier,
27+
title: String = "No games yet.",
28+
subtitle: String = "Check back here later!"
2529
) {
2630
Column(
2731
modifier = modifier,
@@ -34,19 +38,41 @@ fun EmptyState(
3438
)
3539
Spacer(modifier = Modifier.height(16.dp))
3640
Text(
37-
text = "No games yet.",
41+
text = title,
3842
style = heading2.copy(color = GrayPrimary)
3943
)
4044
Spacer(modifier = Modifier.height(8.dp))
4145
Text(
42-
text = "Check back here later!",
46+
text = subtitle,
4347
style = bodyNormal.copy(color = GrayMedium)
4448
)
4549
}
4650
}
4751

52+
@Composable
53+
fun EmptyStateBox(
54+
modifier: Modifier = Modifier,
55+
height: Dp = 550.dp,
56+
title: String = "No games yet.",
57+
subtitle: String = "Check back here later!"
58+
) {
59+
Box(
60+
modifier = modifier
61+
.height(height)
62+
.fillMaxWidth(), contentAlignment = Alignment.Center
63+
) {
64+
EmptyState(title = title, subtitle = subtitle)
65+
}
66+
}
67+
4868
@Preview
4969
@Composable
5070
private fun EmptyStatePreview() = ScorePreview {
5171
EmptyState()
72+
}
73+
74+
@Preview
75+
@Composable
76+
private fun EmptyStateBoxPreview() = ScorePreview {
77+
EmptyStateBox()
5278
}

app/src/main/java/com/cornellappdev/score/components/ScoreBox.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ import com.cornellappdev.score.util.mediumGameData
3939
fun BoxScore(gameData: GameData) {
4040
val maxPeriods = maxOf(
4141
gameData.teamScores.first.scoresByPeriod.size,
42-
gameData.teamScores.second.scoresByPeriod.size,
43-
4
42+
gameData.teamScores.second.scoresByPeriod.size
4443
)
4544
val rowTextStyle = if (maxPeriods > 4) labelsNormal else bodyNormal
4645
Column(
@@ -83,21 +82,28 @@ fun BoxScore(gameData: GameData) {
8382
TeamScoreRow(
8483
teamScore = gameData.teamScores.first,
8584
totalTextColor = saturatedGreen,
85+
maxPeriods,
8686
rowTextStyle
8787
)
8888
HorizontalDivider(thickness = 1.dp, color = CrimsonPrimary)
8989

9090
TeamScoreRow(
9191
teamScore = gameData.teamScores.second,
9292
totalTextColor = GrayMedium,
93+
maxPeriods,
9394
rowTextStyle
9495
)
9596

9697
}
9798
}
9899

99100
@Composable
100-
fun TeamScoreRow(teamScore: TeamScore, totalTextColor: Color, rowTextStyle: TextStyle) {
101+
fun TeamScoreRow(
102+
teamScore: TeamScore,
103+
totalTextColor: Color,
104+
maxPeriods: Int,
105+
rowTextStyle: TextStyle
106+
) {
101107
val showEmpty = teamScore.scoresByPeriod.isEmpty()
102108

103109
Row(
@@ -127,7 +133,7 @@ fun TeamScoreRow(teamScore: TeamScore, totalTextColor: Color, rowTextStyle: Text
127133
)
128134
}
129135

130-
repeat(4 - teamScore.scoresByPeriod.size) {
136+
repeat(maxPeriods - teamScore.scoresByPeriod.size) {
131137
Text(
132138
text = "-",
133139
modifier = Modifier.weight(1f),
@@ -177,5 +183,5 @@ private fun PreviewBoxScoreEmpty() = ScorePreview {
177183
@Preview
178184
@Composable
179185
private fun PreviewTeamScoreRow() = ScorePreview {
180-
TeamScoreRow(gameData.teamScores.first, GrayMedium, bodyNormal)
186+
TeamScoreRow(gameData.teamScores.first, GrayMedium, 4, bodyNormal)
181187
}

app/src/main/java/com/cornellappdev/score/model/Game.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.cornellappdev.score.util.parseDateOrNull
1010
import com.cornellappdev.score.util.parseDateTimeOrNull
1111
import com.cornellappdev.score.util.parseResultScore
1212
import com.cornellappdev.score.util.toGameData
13+
import kotlinx.serialization.Serializable
1314
import java.time.LocalDate
1415
import java.time.LocalDateTime
1516

@@ -151,6 +152,7 @@ data class GameData(
151152
* @property score Current score after the event (e.g., "10 - 7").
152153
* @property description Optional detailed description of the event.
153154
*/
155+
@Serializable
154156
data class ScoreEvent(
155157
val id: Int,
156158
val time: String,
@@ -169,6 +171,7 @@ data class TeamBoxScore(
169171
val name: String
170172
)
171173

174+
@Serializable
172175
data class TeamGameSummary(
173176
val name: String,
174177
val logo: String
@@ -273,12 +276,16 @@ fun List<GameDetailsBoxScore>.toScoreEvents(teamLogo: String): List<ScoreEvent>
273276
val teamName = boxScore.team ?: ""
274277
val corScore = boxScore.corScore ?: 0
275278
val oppScore = boxScore.oppScore ?: 0
276-
279+
val teamSummary = if (teamName == "COR") {
280+
TeamGameSummary(teamName, logo = R.drawable.cornell_logo.toString())
281+
} else {
282+
TeamGameSummary(teamName, logo = teamLogo)
283+
}
277284
ScoreEvent(
278285
id = index,
279286
time = boxScore.time ?: "",
280287
quarter = boxScore.period ?: "",
281-
team = TeamGameSummary(teamName, logo = teamLogo),
288+
team = teamSummary,
282289
eventType = "Score", // TODO: Change to what ios has and not figma
283290
score = "$corScore - $oppScore",
284291
description = boxScore.description

app/src/main/java/com/cornellappdev/score/nav/ScoreNavHost.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package com.cornellappdev.score.nav
22

3+
import GameScoreSummaryScreenDetail
34
import androidx.compose.runtime.Composable
45
import androidx.compose.runtime.CompositionLocalProvider
56
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
67
import androidx.navigation.NavHostController
78
import androidx.navigation.compose.NavHost
89
import androidx.navigation.compose.composable
10+
import androidx.navigation.toRoute
11+
import com.cornellappdev.score.model.ScoreEvent
912
import com.cornellappdev.score.nav.root.ScoreScreens
1013
import com.cornellappdev.score.nav.root.ScoreScreens.Home
1114
import com.cornellappdev.score.screen.GameDetailsScreen
1215
import com.cornellappdev.score.screen.HomeScreen
1316
import com.cornellappdev.score.screen.PastGamesScreen
17+
import kotlinx.serialization.builtins.ListSerializer
18+
import kotlinx.serialization.json.Json
1419

1520
@Composable
1621
fun ScoreNavHost(navController: NavHostController) {
@@ -38,9 +43,27 @@ fun ScoreNavHost(navController: NavHostController) {
3843
}
3944
}
4045
composable<ScoreScreens.GameDetailsPage> {
41-
GameDetailsScreen(onBackArrow = {
46+
GameDetailsScreen(
47+
onBackArrow = {
48+
navController.navigateUp()
49+
},
50+
navigateToGameScoreSummary = { scoreEvents: List<ScoreEvent> ->
51+
val scoreEventsJson =
52+
Json.encodeToString(ListSerializer(ScoreEvent.serializer()), scoreEvents)
53+
navController.navigate(ScoreScreens.GameScoreSummaryPage(scoreEventsJson))
54+
}
55+
)
56+
}
57+
58+
composable<ScoreScreens.GameScoreSummaryPage> { backStackEntry ->
59+
val route = backStackEntry.toRoute<ScoreScreens.GameScoreSummaryPage>()
60+
val scoreEvents: List<ScoreEvent> = Json.decodeFromString(route.scoreEvents)
61+
GameScoreSummaryScreenDetail(scoreEvents = scoreEvents, onBackArrow = {
4262
navController.navigateUp()
4363
})
4464
}
65+
66+
4567
}
46-
}
68+
}
69+

app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ import com.cornellappdev.score.R
2121
import com.cornellappdev.score.nav.ScoreNavHost
2222
import com.cornellappdev.score.nav.ScoreNavigationBar
2323
import com.cornellappdev.score.nav.root.ScoreScreens.GameDetailsPage
24-
import com.cornellappdev.score.nav.root.ScoreScreens.Home
25-
import com.cornellappdev.score.nav.root.ScoreScreens.ScoresScreen
2624
import com.cornellappdev.score.theme.LocalInfiniteLoading
25+
import com.cornellappdev.score.theme.White
2726
import kotlinx.serialization.Serializable
2827

2928
@Composable
@@ -57,12 +56,14 @@ fun RootNavigation(
5756
}
5857

5958

60-
Scaffold(modifier = Modifier.fillMaxSize(), bottomBar = {
61-
if (navBackStackEntry?.toScreen() is GameDetailsPage) {
62-
return@Scaffold
63-
}
64-
ScoreNavigationBar({ navController.navigate(it) }, navBackStackEntry)
65-
}
59+
Scaffold(
60+
modifier = Modifier.fillMaxSize(), bottomBar = {
61+
if (navBackStackEntry?.toScreen() is GameDetailsPage) {
62+
return@Scaffold
63+
}
64+
ScoreNavigationBar({ navController.navigate(it) }, navBackStackEntry)
65+
},
66+
containerColor = White
6667
) { innerPadding ->
6768
Box(modifier = Modifier.padding(innerPadding)) {
6869
CompositionLocalProvider(LocalInfiniteLoading provides animatedValue) {
@@ -84,13 +85,17 @@ sealed class ScoreScreens {
8485

8586
@Serializable
8687
data object ScoresScreen : ScoreScreens()
88+
89+
@Serializable
90+
data class GameScoreSummaryPage(val scoreEvents: String) : ScoreScreens()
8791
}
8892

8993
fun NavBackStackEntry.toScreen(): ScoreScreens? =
9094
when (destination.route?.substringAfterLast(".")?.substringBefore("/")) {
91-
"Home" -> toRoute<Home>()
92-
"GameDetailsPage" -> toRoute<GameDetailsPage>()
93-
"ScoresScreen" -> toRoute<ScoresScreen>()
95+
"Home" -> toRoute<ScoreScreens.Home>()
96+
"GameDetailsPage" -> toRoute<ScoreScreens.GameDetailsPage>()
97+
"ScoresScreen" -> toRoute<ScoreScreens.ScoresScreen>()
98+
"GameScoreSummaryPage" -> toRoute<ScoreScreens.GameScoreSummaryPage>()
9499
else -> throw IllegalArgumentException("Invalid screen")
95100
}
96101

0 commit comments

Comments
 (0)