From e033a35a488fc11188eb62c77d8b45453f04055b Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:23:29 -0400 Subject: [PATCH 01/20] LoadingState set up --- .../score/components/LoadingState.kt | 26 +++++++++++++++++++ .../score/components/LoadingStateBox.kt | 4 +++ 2 files changed, 30 insertions(+) create mode 100644 app/src/main/java/com/cornellappdev/score/components/LoadingState.kt create mode 100644 app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt new file mode 100644 index 0000000..d0116b6 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -0,0 +1,26 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.GrayStroke +import com.cornellappdev.score.theme.Style.heading1 + +@Composable +fun ErrorState(){ + Column( + modifier = Modifier.padding(24.dp) + ){ + Text( + text = "Upcoming", + style = heading1, + color = GrayStroke, + modifier = Modifier.fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt new file mode 100644 index 0000000..d66a2a6 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -0,0 +1,4 @@ +package com.cornellappdev.score.components + +class LoadingStateBox { +} \ No newline at end of file From 8b226d58852c046a9525aa17e58d40a1ae8367d6 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:24:33 -0400 Subject: [PATCH 02/20] LoadingState set up --- .../score/components/LoadingState.kt | 14 +++++++++++-- .../score/components/LoadingStateBox.kt | 21 ++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index d0116b6..eca10ce 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -1,18 +1,20 @@ package com.cornellappdev.score.components import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 @Composable -fun ErrorState(){ +fun LoadingState(){ Column( modifier = Modifier.padding(24.dp) ){ @@ -22,5 +24,13 @@ fun ErrorState(){ color = GrayStroke, modifier = Modifier.fillMaxWidth() ) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 200.dp) } +} + +@Preview +@Composable +private fun LoadingStatePreview(){ + LoadingState() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index d66a2a6..b3bded7 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -1,4 +1,23 @@ package com.cornellappdev.score.components -class LoadingStateBox { +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.Dp +import com.cornellappdev.score.theme.GrayStroke + +@Composable +fun LoadingStateBox(cornerRoundness: Int, height: Dp){ + Box( + modifier = Modifier + .background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness)) + .height(height) + .fillMaxWidth() + ) } \ No newline at end of file From d05dfc859404b4af6174496949d5c93c641defbd Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:43:28 -0400 Subject: [PATCH 03/20] Finish LoadingState --- .../score/components/LoadingState.kt | 110 ++++++++++++++++-- .../score/components/LoadingStateBox.kt | 6 +- 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index eca10ce..688cb01 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -1,12 +1,20 @@ package com.cornellappdev.score.components +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Divider import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -14,23 +22,101 @@ import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 @Composable -fun LoadingState(){ +fun LoadingState() { Column( - modifier = Modifier.padding(24.dp) - ){ - Text( - text = "Upcoming", - style = heading1, - color = GrayStroke, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(16.dp)) - LoadingStateBox(12, 200.dp) + modifier = Modifier.fillMaxSize() + ) { + Column( + modifier = Modifier.padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "Loading Upcoming", + style = heading1, + color = GrayStroke, + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Start) + ) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 200.dp) + Spacer(modifier = Modifier.height(16.dp)) + Row( + modifier = Modifier, + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + for (i in 0 until 3) { + Canvas( + modifier = Modifier + .size(10.dp) + .padding(2.dp) + ) { + drawCircle(color = GrayStroke) + } + } + } + Spacer(modifier = Modifier.height(24.dp)) + Text( + text = "Loading Schedule...", + style = heading1, + color = GrayStroke, + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Start) + ) + LoadingStateBox(100, 50.dp) + Spacer(modifier = Modifier.height(24.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(20.dp) + ) { + for (i in 0 until 5) { + LoadingFilter() + } + } + } + Divider(color = GrayStroke) + Column( + modifier = Modifier.padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(24.dp)) + LoadingStateBox(12, 100.dp) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 100.dp) + } } } +@Composable +private fun LoadingFilter() { + Column( + modifier = Modifier + .width(54.dp) + .height(56.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly + ) { + Canvas( + modifier = Modifier + .size(24.dp) + .padding(2.dp) + ) { + drawCircle(color = GrayStroke) + } + Spacer(modifier = Modifier.height(6.dp)) + LoadingStateBox(100, 12.dp) + } +} + +@Preview +@Composable +private fun LoadingFilterPreview() { + LoadingFilter() +} + @Preview @Composable -private fun LoadingStatePreview(){ +private fun LoadingStatePreview() { LoadingState() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index b3bded7..d3d74ca 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -2,22 +2,20 @@ package com.cornellappdev.score.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.Dp import com.cornellappdev.score.theme.GrayStroke @Composable -fun LoadingStateBox(cornerRoundness: Int, height: Dp){ +fun LoadingStateBox(cornerRoundness: Int, height: Dp) { Box( modifier = Modifier .background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness)) - .height(height) + .height(height) .fillMaxWidth() ) } \ No newline at end of file From c374983f881b3bc0daae021d43779550d4a0c7e7 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:45:14 -0400 Subject: [PATCH 04/20] Spacing fix --- .../main/java/com/cornellappdev/score/components/LoadingState.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index 688cb01..a5229a0 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -64,6 +64,7 @@ fun LoadingState() { .fillMaxWidth() .align(Alignment.Start) ) + Spacer(modifier = Modifier.height(16.dp)) LoadingStateBox(100, 50.dp) Spacer(modifier = Modifier.height(24.dp)) Row( From 83e081f675ddc3a63dbca174589f81e9b303be80 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 13:16:55 -0400 Subject: [PATCH 05/20] Finish ErrorState --- .../score/components/ErrorState.kt | 72 +++++++++++++++++++ app/src/main/res/drawable/ic_cached.xml | 13 ++++ app/src/main/res/drawable/ic_feedback.xml | 13 ++++ 3 files changed, 98 insertions(+) create mode 100644 app/src/main/java/com/cornellappdev/score/components/ErrorState.kt create mode 100644 app/src/main/res/drawable/ic_cached.xml create mode 100644 app/src/main/res/drawable/ic_feedback.xml diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt new file mode 100644 index 0000000..774ba75 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -0,0 +1,72 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.R +import com.cornellappdev.score.theme.CrimsonPrimary +import com.cornellappdev.score.theme.GrayMedium +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.Style.bodyNormal +import com.cornellappdev.score.theme.Style.heading2 + +@Composable +fun ErrorState() { + Column( + modifier = Modifier + .fillMaxWidth() + .height(422.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(R.drawable.ic_feedback), + contentDescription = "feedback bubble" + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "Oops! Schedules failed to load.", + style = heading2.copy(color = GrayPrimary) + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Please try again later.", + style = bodyNormal.copy(color = GrayMedium) + ) + } + Button( + colors = ButtonDefaults.buttonColors(containerColor = CrimsonPrimary), + onClick = {} + ) { + Row() { + Image( + painter = painterResource(R.drawable.ic_cached), + contentDescription = "cached" + ) + Text("Try again") + } + } + } +} + +@Preview +@Composable +private fun ErrorStatePreview() { + ErrorState() +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_cached.xml b/app/src/main/res/drawable/ic_cached.xml new file mode 100644 index 0000000..11b40a3 --- /dev/null +++ b/app/src/main/res/drawable/ic_cached.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_feedback.xml b/app/src/main/res/drawable/ic_feedback.xml new file mode 100644 index 0000000..6379b7f --- /dev/null +++ b/app/src/main/res/drawable/ic_feedback.xml @@ -0,0 +1,13 @@ + + + + + + From e5c21779bf9aa9b0e9aa4aacaae72e9b032f0bf4 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:23:29 -0400 Subject: [PATCH 06/20] LoadingState set up --- .../score/components/LoadingState.kt | 26 +++++++++++++++++++ .../score/components/LoadingStateBox.kt | 4 +++ 2 files changed, 30 insertions(+) create mode 100644 app/src/main/java/com/cornellappdev/score/components/LoadingState.kt create mode 100644 app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt new file mode 100644 index 0000000..d0116b6 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -0,0 +1,26 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.GrayStroke +import com.cornellappdev.score.theme.Style.heading1 + +@Composable +fun ErrorState(){ + Column( + modifier = Modifier.padding(24.dp) + ){ + Text( + text = "Upcoming", + style = heading1, + color = GrayStroke, + modifier = Modifier.fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt new file mode 100644 index 0000000..d66a2a6 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -0,0 +1,4 @@ +package com.cornellappdev.score.components + +class LoadingStateBox { +} \ No newline at end of file From df00252fe2f1544996993ae7fc5ae757b37130d9 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:24:33 -0400 Subject: [PATCH 07/20] LoadingState set up --- .../score/components/LoadingState.kt | 14 +++++++++++-- .../score/components/LoadingStateBox.kt | 21 ++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index d0116b6..eca10ce 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -1,18 +1,20 @@ package com.cornellappdev.score.components import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 @Composable -fun ErrorState(){ +fun LoadingState(){ Column( modifier = Modifier.padding(24.dp) ){ @@ -22,5 +24,13 @@ fun ErrorState(){ color = GrayStroke, modifier = Modifier.fillMaxWidth() ) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 200.dp) } +} + +@Preview +@Composable +private fun LoadingStatePreview(){ + LoadingState() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index d66a2a6..b3bded7 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -1,4 +1,23 @@ package com.cornellappdev.score.components -class LoadingStateBox { +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.Dp +import com.cornellappdev.score.theme.GrayStroke + +@Composable +fun LoadingStateBox(cornerRoundness: Int, height: Dp){ + Box( + modifier = Modifier + .background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness)) + .height(height) + .fillMaxWidth() + ) } \ No newline at end of file From 54c9372cdb5f7d76337a48093386ed885b637e45 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:43:28 -0400 Subject: [PATCH 08/20] Finish LoadingState --- .../score/components/LoadingState.kt | 110 ++++++++++++++++-- .../score/components/LoadingStateBox.kt | 6 +- 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index eca10ce..688cb01 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -1,12 +1,20 @@ package com.cornellappdev.score.components +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Divider import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -14,23 +22,101 @@ import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 @Composable -fun LoadingState(){ +fun LoadingState() { Column( - modifier = Modifier.padding(24.dp) - ){ - Text( - text = "Upcoming", - style = heading1, - color = GrayStroke, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(16.dp)) - LoadingStateBox(12, 200.dp) + modifier = Modifier.fillMaxSize() + ) { + Column( + modifier = Modifier.padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "Loading Upcoming", + style = heading1, + color = GrayStroke, + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Start) + ) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 200.dp) + Spacer(modifier = Modifier.height(16.dp)) + Row( + modifier = Modifier, + horizontalArrangement = Arrangement.spacedBy(32.dp), + ) { + for (i in 0 until 3) { + Canvas( + modifier = Modifier + .size(10.dp) + .padding(2.dp) + ) { + drawCircle(color = GrayStroke) + } + } + } + Spacer(modifier = Modifier.height(24.dp)) + Text( + text = "Loading Schedule...", + style = heading1, + color = GrayStroke, + modifier = Modifier + .fillMaxWidth() + .align(Alignment.Start) + ) + LoadingStateBox(100, 50.dp) + Spacer(modifier = Modifier.height(24.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(20.dp) + ) { + for (i in 0 until 5) { + LoadingFilter() + } + } + } + Divider(color = GrayStroke) + Column( + modifier = Modifier.padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(24.dp)) + LoadingStateBox(12, 100.dp) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 100.dp) + } } } +@Composable +private fun LoadingFilter() { + Column( + modifier = Modifier + .width(54.dp) + .height(56.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly + ) { + Canvas( + modifier = Modifier + .size(24.dp) + .padding(2.dp) + ) { + drawCircle(color = GrayStroke) + } + Spacer(modifier = Modifier.height(6.dp)) + LoadingStateBox(100, 12.dp) + } +} + +@Preview +@Composable +private fun LoadingFilterPreview() { + LoadingFilter() +} + @Preview @Composable -private fun LoadingStatePreview(){ +private fun LoadingStatePreview() { LoadingState() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index b3bded7..d3d74ca 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -2,22 +2,20 @@ package com.cornellappdev.score.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.Dp import com.cornellappdev.score.theme.GrayStroke @Composable -fun LoadingStateBox(cornerRoundness: Int, height: Dp){ +fun LoadingStateBox(cornerRoundness: Int, height: Dp) { Box( modifier = Modifier .background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness)) - .height(height) + .height(height) .fillMaxWidth() ) } \ No newline at end of file From 8c8037cee4daf2972d7d02225f47c753842eca8a Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 12:45:14 -0400 Subject: [PATCH 09/20] Spacing fix --- .../main/java/com/cornellappdev/score/components/LoadingState.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index 688cb01..a5229a0 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -64,6 +64,7 @@ fun LoadingState() { .fillMaxWidth() .align(Alignment.Start) ) + Spacer(modifier = Modifier.height(16.dp)) LoadingStateBox(100, 50.dp) Spacer(modifier = Modifier.height(24.dp)) Row( From 4c38dfe8e6dbe1d86251cf27bc21d398c5ee191e Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 13:16:55 -0400 Subject: [PATCH 10/20] Finish ErrorState --- .../score/components/ErrorState.kt | 72 +++++++++++++++++++ app/src/main/res/drawable/ic_cached.xml | 13 ++++ app/src/main/res/drawable/ic_feedback.xml | 13 ++++ 3 files changed, 98 insertions(+) create mode 100644 app/src/main/java/com/cornellappdev/score/components/ErrorState.kt create mode 100644 app/src/main/res/drawable/ic_cached.xml create mode 100644 app/src/main/res/drawable/ic_feedback.xml diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt new file mode 100644 index 0000000..774ba75 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -0,0 +1,72 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.R +import com.cornellappdev.score.theme.CrimsonPrimary +import com.cornellappdev.score.theme.GrayMedium +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.Style.bodyNormal +import com.cornellappdev.score.theme.Style.heading2 + +@Composable +fun ErrorState() { + Column( + modifier = Modifier + .fillMaxWidth() + .height(422.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(R.drawable.ic_feedback), + contentDescription = "feedback bubble" + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "Oops! Schedules failed to load.", + style = heading2.copy(color = GrayPrimary) + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Please try again later.", + style = bodyNormal.copy(color = GrayMedium) + ) + } + Button( + colors = ButtonDefaults.buttonColors(containerColor = CrimsonPrimary), + onClick = {} + ) { + Row() { + Image( + painter = painterResource(R.drawable.ic_cached), + contentDescription = "cached" + ) + Text("Try again") + } + } + } +} + +@Preview +@Composable +private fun ErrorStatePreview() { + ErrorState() +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_cached.xml b/app/src/main/res/drawable/ic_cached.xml new file mode 100644 index 0000000..11b40a3 --- /dev/null +++ b/app/src/main/res/drawable/ic_cached.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_feedback.xml b/app/src/main/res/drawable/ic_feedback.xml new file mode 100644 index 0000000..6379b7f --- /dev/null +++ b/app/src/main/res/drawable/ic_feedback.xml @@ -0,0 +1,13 @@ + + + + + + From f8608d2be577e2cbbe70cf26c811be4cb888112a Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 14:25:24 -0400 Subject: [PATCH 11/20] Abstracting Error/Loading ui to take custom inputs --- .../score/components/ErrorState.kt | 11 +++++--- .../score/components/LoadingState.kt | 11 +++++--- .../cornellappdev/score/screen/HomeScreen.kt | 25 +++++++------------ 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt index 774ba75..1e60622 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -24,7 +24,10 @@ import com.cornellappdev.score.theme.Style.bodyNormal import com.cornellappdev.score.theme.Style.heading2 @Composable -fun ErrorState() { +fun ErrorState( + onRefresh: () -> Unit, + message: String +) { Column( modifier = Modifier .fillMaxWidth() @@ -41,7 +44,7 @@ fun ErrorState() { ) Spacer(modifier = Modifier.height(16.dp)) Text( - text = "Oops! Schedules failed to load.", + text = message, style = heading2.copy(color = GrayPrimary) ) Spacer(modifier = Modifier.height(8.dp)) @@ -52,7 +55,7 @@ fun ErrorState() { } Button( colors = ButtonDefaults.buttonColors(containerColor = CrimsonPrimary), - onClick = {} + onClick = onRefresh ) { Row() { Image( @@ -68,5 +71,5 @@ fun ErrorState() { @Preview @Composable private fun ErrorStatePreview() { - ErrorState() + ErrorState({}, "Oops! Failed to load.") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt index a5229a0..122570b 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt @@ -22,7 +22,10 @@ import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 @Composable -fun LoadingState() { +fun LoadingState( + topHeader: String, + bottomHeader: String +) { Column( modifier = Modifier.fillMaxSize() ) { @@ -31,7 +34,7 @@ fun LoadingState() { horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "Loading Upcoming", + text = topHeader, style = heading1, color = GrayStroke, modifier = Modifier @@ -57,7 +60,7 @@ fun LoadingState() { } Spacer(modifier = Modifier.height(24.dp)) Text( - text = "Loading Schedule...", + text = bottomHeader, style = heading1, color = GrayStroke, modifier = Modifier @@ -119,5 +122,5 @@ private fun LoadingFilterPreview() { @Preview @Composable private fun LoadingStatePreview() { - LoadingState() + LoadingState("Loading Upcoming...", "Loading Schedules...") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index c8c6478..0671fed 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -2,7 +2,6 @@ package com.cornellappdev.score.screen import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -12,7 +11,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -22,6 +20,8 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.cornellappdev.score.components.ErrorState +import com.cornellappdev.score.components.LoadingState import com.cornellappdev.score.components.SportCard import com.cornellappdev.score.components.SportSelectorHeader import com.cornellappdev.score.components.UpcomingGamesCarousel @@ -46,24 +46,17 @@ fun HomeScreen( ) { when (uiState.loadedState) { is ApiResponse.Loading -> { - //TODO: Add loading screen - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } + LoadingState("Loading Upcoming...", "Loading Schedules...") } is ApiResponse.Error -> { - //TODO: Add Error screen - Box( + Column( modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = "Failed to load games. Please try again.", - ) + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Bottom + ){ + ErrorState({ homeViewModel.onRefresh() }, "Oops! Schedules failed to load.") + Spacer(modifier = Modifier.height(70.dp)) } } From 5f986aaf29a8e1687e8f86b2fa774f6249f15f04 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 14:25:35 -0400 Subject: [PATCH 12/20] add onRefresh --- .../com/cornellappdev/score/viewmodel/HomeViewModel.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/com/cornellappdev/score/viewmodel/HomeViewModel.kt b/app/src/main/java/com/cornellappdev/score/viewmodel/HomeViewModel.kt index 2121b70..f4f6778 100644 --- a/app/src/main/java/com/cornellappdev/score/viewmodel/HomeViewModel.kt +++ b/app/src/main/java/com/cornellappdev/score/viewmodel/HomeViewModel.kt @@ -60,6 +60,14 @@ class HomeViewModel @Inject constructor( } } + fun onRefresh() { + applyMutation { + copy(loadedState = ApiResponse.Loading) + } + + scoreRepository.fetchGames() + } + fun onGenderSelected(gender: GenderDivision) { applyMutation { copy( From b781e277fb89bcb12b545778d720f008d47672e5 Mon Sep 17 00:00:00 2001 From: amjiao Date: Sat, 22 Mar 2025 14:55:11 -0400 Subject: [PATCH 13/20] GameDetailsLoadingState --- .../components/GameDetailsLoadingState.kt | 118 ++++++++++++++++++ .../main/res/drawable/ic_right_chevron.xml | 13 ++ 2 files changed, 131 insertions(+) create mode 100644 app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt create mode 100644 app/src/main/res/drawable/ic_right_chevron.xml diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt new file mode 100644 index 0000000..d20b1c9 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt @@ -0,0 +1,118 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme.typography +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.R +import com.cornellappdev.score.theme.GrayLight +import com.cornellappdev.score.theme.GrayStroke + +@Composable +fun GameDetailsLoadingState() { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Row( + modifier = Modifier + .background(color = GrayStroke) + .fillMaxWidth() + .height(185.dp), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Canvas( + modifier = Modifier + .size(72.dp) + ) { + drawCircle(color = GrayLight) + } + Spacer(modifier = Modifier.width(24.dp)) + Box( + modifier = Modifier + .width(100.dp) + .height(33.dp) + .background(color = GrayLight, shape = RoundedCornerShape(100)) + ) + Spacer(modifier = Modifier.width(24.dp)) + Canvas( + modifier = Modifier + .size(72.dp) + ) { + drawCircle(color = GrayLight) + } + } + Column( + modifier = Modifier.padding(24.dp) + ) { + Box( + modifier = Modifier + .width(100.dp) + .height(16.dp) + .background(color = GrayStroke, shape = RoundedCornerShape(12)) + ) + Spacer(modifier = Modifier.height(12.dp)) + Box( + modifier = Modifier + .width(200.dp) + .height(32.dp) + .background(color = GrayStroke, shape = RoundedCornerShape(100)) + ) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(12, 16.dp) + + Spacer(modifier = Modifier.height(24.dp)) + LoadingStateBox(8, 125.dp) + Spacer(modifier = Modifier.height(24.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "Loading Score Summary", + color = GrayStroke, + style = typography.titleMedium, + modifier = Modifier.weight(1f) + ) + + Image( + painter = painterResource(R.drawable.ic_right_chevron), + contentDescription = "right chevron" + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(8, 48.dp) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(8, 48.dp) + Spacer(modifier = Modifier.height(16.dp)) + LoadingStateBox(8, 48.dp) + } + } +} + +@Preview +@Composable +private fun GameDetailsLoadingStatePreview() { + GameDetailsLoadingState() +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_right_chevron.xml b/app/src/main/res/drawable/ic_right_chevron.xml new file mode 100644 index 0000000..395c7bc --- /dev/null +++ b/app/src/main/res/drawable/ic_right_chevron.xml @@ -0,0 +1,13 @@ + + + + + + From 0b1963f6df0b7743553f1382148033e59792a644 Mon Sep 17 00:00:00 2001 From: amjiao Date: Mon, 7 Apr 2025 12:10:16 -0400 Subject: [PATCH 14/20] PR fixes --- .../score/components/ErrorState.kt | 21 +++++--- .../components/GameDetailsLoadingState.kt | 41 ++++++--------- .../{LoadingState.kt => LoadingScreen.kt} | 19 ++++--- .../score/components/LoadingStateBox.kt | 31 ++++++++++-- .../score/nav/root/RootNavigation.kt | 44 ++++++++++++---- .../cornellappdev/score/screen/HomeScreen.kt | 6 +-- .../com/cornellappdev/score/util/ColorUtil.kt | 50 +++++++++++++++++++ 7 files changed, 156 insertions(+), 56 deletions(-) rename app/src/main/java/com/cornellappdev/score/components/{LoadingState.kt => LoadingScreen.kt} (87%) diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt index 1e60622..780e4f1 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults @@ -26,15 +26,16 @@ import com.cornellappdev.score.theme.Style.heading2 @Composable fun ErrorState( onRefresh: () -> Unit, - message: String + message: String, + modifier: Modifier = Modifier ) { Column( - modifier = Modifier - .fillMaxWidth() - .height(422.dp), + modifier = modifier + .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween + verticalArrangement = Arrangement.spacedBy(100.dp) ) { + Spacer(modifier = Modifier.height(200.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally ) { @@ -53,18 +54,22 @@ fun ErrorState( style = bodyNormal.copy(color = GrayMedium) ) } + Button( colors = ButtonDefaults.buttonColors(containerColor = CrimsonPrimary), onClick = onRefresh ) { - Row() { + Row( + verticalAlignment = Alignment.CenterVertically + ) { Image( painter = painterResource(R.drawable.ic_cached), - contentDescription = "cached" + contentDescription = "refresh icon" ) Text("Try again") } } + Spacer(modifier = Modifier.height(70.dp)) } } diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt index d20b1c9..df23797 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.Canvas import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -13,7 +12,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -23,17 +21,23 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.R -import com.cornellappdev.score.theme.GrayLight import com.cornellappdev.score.theme.GrayStroke +import com.cornellappdev.score.util.LocalInfiniteLoading +import com.cornellappdev.score.util.Stroke +import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.util.interpolateColorHSV @Composable -fun GameDetailsLoadingState() { +fun GameDetailsLoadingState( + modifier: Modifier = Modifier +) { + val shimmerColor = interpolateColorHSV(Wash, Stroke, LocalInfiniteLoading.current) Column( - modifier = Modifier.fillMaxWidth() + modifier = modifier.fillMaxWidth() ) { Row( modifier = Modifier - .background(color = GrayStroke) + .background(color = shimmerColor) .fillMaxWidth() .height(185.dp), horizontalArrangement = Arrangement.Center, @@ -43,39 +47,24 @@ fun GameDetailsLoadingState() { modifier = Modifier .size(72.dp) ) { - drawCircle(color = GrayLight) + drawCircle(color = shimmerColor) } Spacer(modifier = Modifier.width(24.dp)) - Box( - modifier = Modifier - .width(100.dp) - .height(33.dp) - .background(color = GrayLight, shape = RoundedCornerShape(100)) - ) + LoadingStateBox(100, 33.dp, Modifier.width(100.dp)) Spacer(modifier = Modifier.width(24.dp)) Canvas( modifier = Modifier .size(72.dp) ) { - drawCircle(color = GrayLight) + drawCircle(color = shimmerColor) } } Column( modifier = Modifier.padding(24.dp) ) { - Box( - modifier = Modifier - .width(100.dp) - .height(16.dp) - .background(color = GrayStroke, shape = RoundedCornerShape(12)) - ) + LoadingStateBox(12, 16.dp, Modifier.width(100.dp)) Spacer(modifier = Modifier.height(12.dp)) - Box( - modifier = Modifier - .width(200.dp) - .height(32.dp) - .background(color = GrayStroke, shape = RoundedCornerShape(100)) - ) + LoadingStateBox(100, 32.dp, Modifier.width(200.dp)) Spacer(modifier = Modifier.height(16.dp)) LoadingStateBox(12, 16.dp) diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt similarity index 87% rename from app/src/main/java/com/cornellappdev/score/components/LoadingState.kt rename to app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt index 122570b..13ed523 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt @@ -20,14 +20,19 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 +import com.cornellappdev.score.util.LocalInfiniteLoading +import com.cornellappdev.score.util.Stroke +import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.util.interpolateColorHSV @Composable -fun LoadingState( +fun LoadingScreen( topHeader: String, - bottomHeader: String + bottomHeader: String, + modifier: Modifier = Modifier ) { Column( - modifier = Modifier.fillMaxSize() + modifier = modifier.fillMaxSize() ) { Column( modifier = Modifier.padding(24.dp), @@ -94,6 +99,8 @@ fun LoadingState( @Composable private fun LoadingFilter() { + val shimmerColor = interpolateColorHSV(Wash, Stroke, LocalInfiniteLoading.current) + Column( modifier = Modifier .width(54.dp) @@ -106,7 +113,7 @@ private fun LoadingFilter() { .size(24.dp) .padding(2.dp) ) { - drawCircle(color = GrayStroke) + drawCircle(color = shimmerColor) } Spacer(modifier = Modifier.height(6.dp)) LoadingStateBox(100, 12.dp) @@ -121,6 +128,6 @@ private fun LoadingFilterPreview() { @Preview @Composable -private fun LoadingStatePreview() { - LoadingState("Loading Upcoming...", "Loading Schedules...") +private fun LoadingScreenPreview() { + LoadingScreen("Loading Upcoming...", "Loading Schedules...") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index d3d74ca..a91261d 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -7,15 +7,38 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp -import com.cornellappdev.score.theme.GrayStroke +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.util.LocalInfiniteLoading +import com.cornellappdev.score.util.Stroke +import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.util.interpolateColorHSV @Composable -fun LoadingStateBox(cornerRoundness: Int, height: Dp) { +fun LoadingStateBox( + cornerRoundness: Int, + height: Dp, + modifier: Modifier = Modifier.fillMaxWidth() +) { Box( - modifier = Modifier - .background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness)) + modifier = modifier .height(height) + .background( + color = interpolateColorHSV( + Wash, + Stroke, + LocalInfiniteLoading.current + ), + shape = RoundedCornerShape(cornerRoundness) + ) .fillMaxWidth() ) + +} + +@Preview +@Composable +private fun LoadingStateBoxPreview() { + LoadingStateBox(12, 16.dp) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt b/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt index 440ad57..9a48e21 100644 --- a/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt +++ b/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt @@ -1,12 +1,18 @@ package com.cornellappdev.score.nav.root +import androidx.compose.animation.core.InfiniteRepeatableSpec +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.keyframes +import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.cornellappdev.score.screen.HomeScreen +import com.cornellappdev.score.util.LocalInfiniteLoading import kotlinx.serialization.Serializable @Composable @@ -16,26 +22,46 @@ fun RootNavigation( val navController = rememberNavController() val uiState = rootNavigationViewModel.collectUiStateValue() + val transition = rememberInfiniteTransition() + // Animate a value from 0 to 1 infinitely + val animatedValue = transition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = InfiniteRepeatableSpec( + animation = keyframes { + durationMillis = 2000 + 0f at 0 + 1f at 1000 + 0f at 2000 + } + ), + label = "infinite loading" + ).value + LaunchedEffect(uiState.navigationEvent) { uiState.navigationEvent?.consumeSuspend { screen -> navController.navigate(screen) } } - NavHost( - navController = navController, - startDestination = ScoreRootScreens.Home + CompositionLocalProvider( + LocalInfiniteLoading provides animatedValue ) { - composable { - HomeScreen() - } + NavHost( + navController = navController, + startDestination = ScoreRootScreens.Home + ) { + composable { + HomeScreen() + } - composable { + composable { - } + } - composable { + composable { + } } } } diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index 0671fed..75360fe 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.cornellappdev.score.components.ErrorState -import com.cornellappdev.score.components.LoadingState +import com.cornellappdev.score.components.LoadingScreen import com.cornellappdev.score.components.SportCard import com.cornellappdev.score.components.SportSelectorHeader import com.cornellappdev.score.components.UpcomingGamesCarousel @@ -46,7 +46,7 @@ fun HomeScreen( ) { when (uiState.loadedState) { is ApiResponse.Loading -> { - LoadingState("Loading Upcoming...", "Loading Schedules...") + LoadingScreen("Loading Upcoming...", "Loading Schedules...") } is ApiResponse.Error -> { @@ -54,7 +54,7 @@ fun HomeScreen( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Bottom - ){ + ) { ErrorState({ homeViewModel.onRefresh() }, "Oops! Schedules failed to load.") Spacer(modifier = Modifier.height(70.dp)) } diff --git a/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt b/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt index 89e66bb..1594f8d 100644 --- a/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt +++ b/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt @@ -1,11 +1,61 @@ package com.cornellappdev.score.util +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color +val Wash = Color(0xFFF4F4F4) +val Stroke = Color(0xFFD6D6D6) +val LocalInfiniteLoading = compositionLocalOf { error("No infinite loading provided") } + /** * Converts a hexcode String into Color object */ fun parseColor(color: String): Color { val colorInt = Integer.parseInt(color.removePrefix("#"), 16) return Color(colorInt) +} + +/** + * Interpolates between two colors based on a given fraction. + */ +fun interpolateColorHSV(startColor: Color, endColor: Color, fraction: Float): Color { + // Clamp the fraction to be between 0 and 1 + val clampedFraction = fraction.coerceIn(0f, 1f) + + // Convert start and end colors to HSV + val startHSV = FloatArray(3) + val endHSV = FloatArray(3) + android.graphics.Color.colorToHSV( + android.graphics.Color.argb( + (startColor.alpha * 255).toInt(), + (startColor.red * 255).toInt(), + (startColor.green * 255).toInt(), + (startColor.blue * 255).toInt() + ), + startHSV + ) + android.graphics.Color.colorToHSV( + android.graphics.Color.argb( + (endColor.alpha * 255).toInt(), + (endColor.red * 255).toInt(), + (endColor.green * 255).toInt(), + (endColor.blue * 255).toInt() + ), + endHSV + ) + + // Interpolate HSV values + val hue = startHSV[0] + (endHSV[0] - startHSV[0]) * clampedFraction + val saturation = startHSV[1] + (endHSV[1] - startHSV[1]) * clampedFraction + val value = startHSV[2] + (endHSV[2] - startHSV[2]) * clampedFraction + + // Convert back to RGB + val rgb = android.graphics.Color.HSVToColor(floatArrayOf(hue, saturation, value)) + + return Color( + red = ((rgb shr 16) and 0xFF) / 255f, + green = ((rgb shr 8) and 0xFF) / 255f, + blue = (rgb and 0xFF) / 255f, + alpha = ((rgb shr 24) and 0xFF) / 255f + ) } \ No newline at end of file From acc40c8cb9f81d60fa0285299bbabeb03adea46a Mon Sep 17 00:00:00 2001 From: amjiao Date: Mon, 7 Apr 2025 12:21:03 -0400 Subject: [PATCH 15/20] Import fix --- app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index 0d013ad..3e9ab7c 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.cornellappdev.score.components.ErrorState import com.cornellappdev.score.components.LoadingScreen -import com.cornellappdev.score.components.SportCard import com.cornellappdev.score.components.GamesCarousel import com.cornellappdev.score.components.GameCard import com.cornellappdev.score.components.SportSelectorHeader From 42c8fe4e24b3892f594b55f56ac6dafeaeea840a Mon Sep 17 00:00:00 2001 From: amjiao Date: Tue, 8 Apr 2025 23:51:50 -0400 Subject: [PATCH 16/20] ScorePreview + small fixes --- .../score/components/ErrorState.kt | 2 +- .../components/GameDetailsLoadingState.kt | 12 ++++--- .../score/components/LoadingScreen.kt | 14 ++++++--- .../score/components/LoadingStateBox.kt | 10 +++--- .../score/components/ScorePreview.kt | 31 +++++++++++++++++++ .../score/nav/root/RootNavigation.kt | 5 ++- .../com/cornellappdev/score/theme/Color.kt | 7 ++++- .../com/cornellappdev/score/util/ColorUtil.kt | 5 --- 8 files changed, 62 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt index 780e4f1..854a192 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -73,7 +73,7 @@ fun ErrorState( } } -@Preview +@Preview(showBackground = true) @Composable private fun ErrorStatePreview() { ErrorState({}, "Oops! Failed to load.") diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt index df23797..90a62c6 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt @@ -22,9 +22,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.R import com.cornellappdev.score.theme.GrayStroke -import com.cornellappdev.score.util.LocalInfiniteLoading -import com.cornellappdev.score.util.Stroke -import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.theme.LocalInfiniteLoading +import com.cornellappdev.score.theme.Stroke +import com.cornellappdev.score.theme.Wash import com.cornellappdev.score.util.interpolateColorHSV @Composable @@ -102,6 +102,8 @@ fun GameDetailsLoadingState( @Preview @Composable -private fun GameDetailsLoadingStatePreview() { - GameDetailsLoadingState() +private fun GameDetailsLoadingStatePreview(){ + ScorePreview { + GameDetailsLoadingState() + } } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt index 13ed523..d45a1d7 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt @@ -20,9 +20,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.Style.heading1 -import com.cornellappdev.score.util.LocalInfiniteLoading -import com.cornellappdev.score.util.Stroke -import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.theme.LocalInfiniteLoading +import com.cornellappdev.score.theme.Stroke +import com.cornellappdev.score.theme.Wash import com.cornellappdev.score.util.interpolateColorHSV @Composable @@ -123,11 +123,15 @@ private fun LoadingFilter() { @Preview @Composable private fun LoadingFilterPreview() { - LoadingFilter() + ScorePreview { + LoadingFilter() + } } @Preview @Composable private fun LoadingScreenPreview() { - LoadingScreen("Loading Upcoming...", "Loading Schedules...") + ScorePreview { + LoadingScreen("Loading Upcoming...", "Loading Schedules...") + } } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index a91261d..4743654 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -10,9 +10,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.cornellappdev.score.util.LocalInfiniteLoading -import com.cornellappdev.score.util.Stroke -import com.cornellappdev.score.util.Wash +import com.cornellappdev.score.theme.LocalInfiniteLoading +import com.cornellappdev.score.theme.Stroke +import com.cornellappdev.score.theme.Wash import com.cornellappdev.score.util.interpolateColorHSV @Composable @@ -40,5 +40,7 @@ fun LoadingStateBox( @Preview @Composable private fun LoadingStateBoxPreview() { - LoadingStateBox(12, 16.dp) + ScorePreview { + LoadingStateBox(12, 16.dp) + } } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt new file mode 100644 index 0000000..1922f79 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt @@ -0,0 +1,31 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.theme.LocalInfiniteLoading + +@Composable +fun ScorePreview( + padding: Dp = 0.dp, + backgroundColor: Color = Color.White, + content: @Composable () -> Unit +) { + CompositionLocalProvider( + LocalInfiniteLoading provides 0f + ) { + Column( + modifier = Modifier + .background(backgroundColor) + .padding(padding) + ) { + content() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt b/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt index ba88810..696eec8 100644 --- a/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt +++ b/app/src/main/java/com/cornellappdev/score/nav/root/RootNavigation.kt @@ -29,14 +29,13 @@ import com.cornellappdev.score.R import com.cornellappdev.score.nav.root.ScoreRootScreens.Home.toScreen import com.cornellappdev.score.screen.GameDetailsScreen import com.cornellappdev.score.screen.HomeScreen -import com.cornellappdev.score.util.LocalInfiniteLoading import com.cornellappdev.score.screen.PastGamesScreen import com.cornellappdev.score.theme.CrimsonPrimary import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.LocalInfiniteLoading import com.cornellappdev.score.theme.Style.bodyMedium import com.cornellappdev.score.theme.White import kotlinx.serialization.Serializable -import java.time.LocalDate @Composable fun RootNavigation( @@ -100,7 +99,7 @@ fun RootNavigation( } ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { - CompositionLocalProvider(LocalInfiniteLoading provides animatedValue){ + CompositionLocalProvider(LocalInfiniteLoading provides animatedValue) { NavHost( navController = navController, startDestination = ScoreRootScreens.Home diff --git a/app/src/main/java/com/cornellappdev/score/theme/Color.kt b/app/src/main/java/com/cornellappdev/score/theme/Color.kt index 2a45d4d..a3a20ec 100644 --- a/app/src/main/java/com/cornellappdev/score/theme/Color.kt +++ b/app/src/main/java/com/cornellappdev/score/theme/Color.kt @@ -1,5 +1,6 @@ package com.cornellappdev.score.theme +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color val GrayPrimary = Color(0xFF333333) @@ -22,4 +23,8 @@ val AmbientColor = Color(0x12000000) //placeholders, will be replaced once we get backend data val CornellRed = Color(0x66B31B1B) val PennBlue = Color(0x66021E59) -val PrincetonOrange = Color(0x66FF6000) \ No newline at end of file +val PrincetonOrange = Color(0x66FF6000) + +val Wash = Color(0xFFF4F4F4) +val Stroke = Color(0xFFD6D6D6) +val LocalInfiniteLoading = compositionLocalOf { error("No infinite loading provided") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt b/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt index 1594f8d..888a000 100644 --- a/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt +++ b/app/src/main/java/com/cornellappdev/score/util/ColorUtil.kt @@ -1,12 +1,7 @@ package com.cornellappdev.score.util -import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color -val Wash = Color(0xFFF4F4F4) -val Stroke = Color(0xFFD6D6D6) -val LocalInfiniteLoading = compositionLocalOf { error("No infinite loading provided") } - /** * Converts a hexcode String into Color object */ From a992ad3488b289db8ca0cb68029d230267297e81 Mon Sep 17 00:00:00 2001 From: amjiao Date: Wed, 9 Apr 2025 00:31:19 -0400 Subject: [PATCH 17/20] Remove redundant code --- .../java/com/cornellappdev/score/screen/HomeScreen.kt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index 85c03bc..32185b5 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -54,14 +54,7 @@ fun HomeScreen( } is ApiResponse.Error -> { - Column( - modifier = Modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Bottom - ) { - ErrorState({ homeViewModel.onRefresh() }, "Oops! Schedules failed to load.") - Spacer(modifier = Modifier.height(70.dp)) - } + ErrorState({ homeViewModel.onRefresh() }, "Oops! Schedules failed to load.") } is ApiResponse.Success -> { From 5daf380bf5ba4795049c8cdac014c82c344e3628 Mon Sep 17 00:00:00 2001 From: amjiao Date: Wed, 9 Apr 2025 00:35:06 -0400 Subject: [PATCH 18/20] Rename to GameDetailsLoadingScreen for consistency --- ...GameDetailsLoadingState.kt => GameDetailsLoadingScreen.kt} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename app/src/main/java/com/cornellappdev/score/components/{GameDetailsLoadingState.kt => GameDetailsLoadingScreen.kt} (98%) diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt similarity index 98% rename from app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt rename to app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt index 90a62c6..d481672 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt @@ -28,7 +28,7 @@ import com.cornellappdev.score.theme.Wash import com.cornellappdev.score.util.interpolateColorHSV @Composable -fun GameDetailsLoadingState( +fun GameDetailsLoadingScreen( modifier: Modifier = Modifier ) { val shimmerColor = interpolateColorHSV(Wash, Stroke, LocalInfiniteLoading.current) @@ -104,6 +104,6 @@ fun GameDetailsLoadingState( @Composable private fun GameDetailsLoadingStatePreview(){ ScorePreview { - GameDetailsLoadingState() + GameDetailsLoadingScreen() } } \ No newline at end of file From b7739a4c54da192d500b99d5c7d5dd4372f6f83f Mon Sep 17 00:00:00 2001 From: amjiao Date: Wed, 9 Apr 2025 17:54:09 -0400 Subject: [PATCH 19/20] PR fixes # Conflicts: # app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt --- .../score/components/ErrorState.kt | 4 +-- .../components/GameDetailsLoadingScreen.kt | 6 ++--- .../score/components/LoadingScreen.kt | 12 +++------ .../score/components/LoadingStateBox.kt | 6 ++--- .../score/components/ScorePreview.kt | 24 ++++++++++++++++-- .../score/screen/PastGamesScreen.kt | 25 ++++--------------- .../com/cornellappdev/score/theme/Color.kt | 4 +-- .../score/theme/CompositionLocals.kt | 5 ++++ .../score/viewmodel/PastGamesViewModel.kt | 8 ++++++ 9 files changed, 51 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/com/cornellappdev/score/theme/CompositionLocals.kt diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt index 854a192..ded2a29 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -73,8 +73,8 @@ fun ErrorState( } } -@Preview(showBackground = true) +@Preview @Composable -private fun ErrorStatePreview() { +private fun ErrorStatePreview() = ScorePreview{ ErrorState({}, "Oops! Failed to load.") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt index d481672..a9a924f 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt @@ -102,8 +102,6 @@ fun GameDetailsLoadingScreen( @Preview @Composable -private fun GameDetailsLoadingStatePreview(){ - ScorePreview { - GameDetailsLoadingScreen() - } +private fun GameDetailsLoadingStatePreview() = ScorePreview{ + GameDetailsLoadingScreen() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt index d45a1d7..39b6e22 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt @@ -122,16 +122,12 @@ private fun LoadingFilter() { @Preview @Composable -private fun LoadingFilterPreview() { - ScorePreview { - LoadingFilter() - } +private fun LoadingFilterPreview() = ScorePreview{ + LoadingFilter() } @Preview @Composable -private fun LoadingScreenPreview() { - ScorePreview { - LoadingScreen("Loading Upcoming...", "Loading Schedules...") - } +private fun LoadingScreenPreview() = ScorePreview { + LoadingScreen("Loading Upcoming...", "Loading Schedules...") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt index 4743654..86123a8 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingStateBox.kt @@ -39,8 +39,6 @@ fun LoadingStateBox( @Preview @Composable -private fun LoadingStateBoxPreview() { - ScorePreview { - LoadingStateBox(12, 16.dp) - } +private fun LoadingStateBoxPreview() = ScorePreview { + LoadingStateBox(12, 16.dp) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt index 1922f79..1593a11 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt @@ -1,5 +1,9 @@ package com.cornellappdev.score.components +import androidx.compose.animation.core.InfiniteRepeatableSpec +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.keyframes +import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -17,12 +21,28 @@ fun ScorePreview( backgroundColor: Color = Color.White, content: @Composable () -> Unit ) { + val transition = rememberInfiniteTransition() + + val animatedValue = transition.animateFloat( + initialValue = 0f, + targetValue = 1f, + animationSpec = InfiniteRepeatableSpec( + animation = keyframes { + durationMillis = 2000 + 0f at 0 + 1f at 1000 + 0f at 2000 + } + ), + label = "infinite loading" + ).value + CompositionLocalProvider( - LocalInfiniteLoading provides 0f + LocalInfiniteLoading provides animatedValue ) { Column( modifier = Modifier - .background(backgroundColor) + .background(color = backgroundColor) .padding(padding) ) { content() diff --git a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt index ded0052..8f153bd 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt @@ -1,18 +1,15 @@ package com.cornellappdev.score.screen -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -21,7 +18,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.cornellappdev.score.components.ErrorState import com.cornellappdev.score.components.GamesCarousel +import com.cornellappdev.score.components.LoadingScreen import com.cornellappdev.score.components.PastGameCard import com.cornellappdev.score.components.SportSelectorHeader import com.cornellappdev.score.model.ApiResponse @@ -49,25 +48,11 @@ fun PastGamesScreen( ) { when (uiState.loadedState) { is ApiResponse.Loading -> { - //TODO: Add loading screen - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } + LoadingScreen("Loading Latest", "Loading Scores") } is ApiResponse.Error -> { - //TODO: Add Error screen - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = "Failed to load games. Please try again.", - ) - } + ErrorState({ pastGamesViewModel.onRefresh() }, "Oops! Scores failed to load.") } is ApiResponse.Success -> { diff --git a/app/src/main/java/com/cornellappdev/score/theme/Color.kt b/app/src/main/java/com/cornellappdev/score/theme/Color.kt index a3a20ec..a4f8fa5 100644 --- a/app/src/main/java/com/cornellappdev/score/theme/Color.kt +++ b/app/src/main/java/com/cornellappdev/score/theme/Color.kt @@ -1,6 +1,5 @@ package com.cornellappdev.score.theme -import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color val GrayPrimary = Color(0xFF333333) @@ -26,5 +25,4 @@ val PennBlue = Color(0x66021E59) val PrincetonOrange = Color(0x66FF6000) val Wash = Color(0xFFF4F4F4) -val Stroke = Color(0xFFD6D6D6) -val LocalInfiniteLoading = compositionLocalOf { error("No infinite loading provided") } \ No newline at end of file +val Stroke = Color(0xFFD6D6D6) \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/theme/CompositionLocals.kt b/app/src/main/java/com/cornellappdev/score/theme/CompositionLocals.kt new file mode 100644 index 0000000..346f07d --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/theme/CompositionLocals.kt @@ -0,0 +1,5 @@ +package com.cornellappdev.score.theme + +import androidx.compose.runtime.compositionLocalOf + +val LocalInfiniteLoading = compositionLocalOf { error("No infinite loading provided") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/viewmodel/PastGamesViewModel.kt b/app/src/main/java/com/cornellappdev/score/viewmodel/PastGamesViewModel.kt index 4df8393..43a2888 100644 --- a/app/src/main/java/com/cornellappdev/score/viewmodel/PastGamesViewModel.kt +++ b/app/src/main/java/com/cornellappdev/score/viewmodel/PastGamesViewModel.kt @@ -59,6 +59,14 @@ class PastGamesViewModel @Inject constructor( } } + fun onRefresh() { + applyMutation { + copy(loadedState = ApiResponse.Loading) + } + + scoreRepository.fetchGames() + } + fun onGenderSelected(gender: GenderDivision) { applyMutation { copy( From c4806696d4729c3297fb59a2b2ae09b9dcef4de8 Mon Sep 17 00:00:00 2001 From: zachseidner1 Date: Wed, 9 Apr 2025 21:24:24 -0400 Subject: [PATCH 20/20] Quick migration of remaining previews --- .../score/components/EmptyStateMessage.kt | 16 ++--- .../score/components/ErrorState.kt | 2 +- .../score/components/FeaturedGameCard.kt | 6 +- .../score/components/GameCard.kt | 18 ++--- .../components/GameDetailsLoadingScreen.kt | 2 +- .../score/components/GameScoreHeader.kt | 2 +- .../score/components/GamesCarousel.kt | 5 +- .../score/components/LoadingScreen.kt | 4 +- .../score/components/NavigationHeader.kt | 70 ++++++++----------- .../score/components/PastGameCard.kt | 15 +++- .../score/components/ScoreBox.kt | 20 +++--- .../score/components/ScorePreview.kt | 3 +- .../score/components/ScoreSummary.kt | 7 +- .../score/components/SportSelectorHeader.kt | 2 +- .../score/components/TimeUntilStartCard.kt | 2 +- .../score/screen/GameDetailsScreen.kt | 11 ++- .../score/screen/GameScoreSummaryScreen.kt | 48 +++++++------ .../cornellappdev/score/screen/HomeScreen.kt | 7 +- .../score/screen/PastGamesScreen.kt | 5 +- 19 files changed, 128 insertions(+), 117 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/score/components/EmptyStateMessage.kt b/app/src/main/java/com/cornellappdev/score/components/EmptyStateMessage.kt index c7ab7c8..5ba58cc 100644 --- a/app/src/main/java/com/cornellappdev/score/components/EmptyStateMessage.kt +++ b/app/src/main/java/com/cornellappdev/score/components/EmptyStateMessage.kt @@ -1,8 +1,6 @@ package com.cornellappdev.score.components import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height @@ -12,7 +10,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview @@ -23,11 +20,14 @@ import com.cornellappdev.score.theme.GrayMedium import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.Style.bodyNormal import com.cornellappdev.score.theme.Style.heading2 +import com.cornellappdev.score.theme.White @Composable fun EmptyStateMessage(modifier: Modifier = Modifier) { - Column(modifier = modifier.width(158.dp), - horizontalAlignment = Alignment.CenterHorizontally) { + Column( + modifier = modifier.width(158.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { Image( painter = painterResource(id = R.drawable.ic_speaker), contentDescription = "Speaker Icon", @@ -52,8 +52,6 @@ fun EmptyStateMessage(modifier: Modifier = Modifier) { @Preview @Composable -private fun PreviewEmptyStateMessage() { - Box(modifier = Modifier.background(Color.White)) { - EmptyStateMessage() - } +private fun PreviewEmptyStateMessage() = ScorePreview { + EmptyStateMessage() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt index ded2a29..cb45ca9 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ErrorState.kt @@ -75,6 +75,6 @@ fun ErrorState( @Preview @Composable -private fun ErrorStatePreview() = ScorePreview{ +private fun ErrorStatePreview() = ScorePreview { ErrorState({}, "Oops! Failed to load.") } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/FeaturedGameCard.kt b/app/src/main/java/com/cornellappdev/score/components/FeaturedGameCard.kt index 3d0d0a1..ed55c55 100644 --- a/app/src/main/java/com/cornellappdev/score/components/FeaturedGameCard.kt +++ b/app/src/main/java/com/cornellappdev/score/components/FeaturedGameCard.kt @@ -110,7 +110,7 @@ fun FeaturedGameHeader( @Preview @Composable -private fun FeaturedGameCardPreview() { +private fun FeaturedGameCardPreview() = ScorePreview { FeaturedGameHeader( leftTeamLogo = painterResource(R.drawable.cornell_logo), rightTeamLogo = "https://cornellbigred.com/images/logos/YALE_LOGO_2020.png?width=80&height=80&mode=max", @@ -177,9 +177,9 @@ fun FeaturedGameCard( } } -@Preview(showBackground = true) +@Preview @Composable -private fun GameScheduleScreen() { +private fun GameScheduleScreen() = ScorePreview { FeaturedGameCard( leftTeamLogo = painterResource(R.drawable.cornell_logo), rightTeamLogo = "https://cornellbigred.com/images/logos/penn_200x200.png?width=80&height=80&mode=max",//painterResource(R.drawable.penn_logo), diff --git a/app/src/main/java/com/cornellappdev/score/components/GameCard.kt b/app/src/main/java/com/cornellappdev/score/components/GameCard.kt index 831a32f..7d28d31 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameCard.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameCard.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -18,6 +17,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card @@ -36,21 +36,15 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.cornellappdev.score.R -import com.cornellappdev.score.model.GameCardData import com.cornellappdev.score.theme.AmbientColor import com.cornellappdev.score.theme.GrayMedium import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.GrayStroke import com.cornellappdev.score.theme.SpotColor import com.cornellappdev.score.theme.Style.bodyNormal -import com.cornellappdev.score.theme.Style.dateText import com.cornellappdev.score.theme.Style.heading2 import com.cornellappdev.score.theme.Style.labelsNormal -import com.cornellappdev.score.theme.Style.teamName -import com.cornellappdev.score.theme.Style.universityText import com.cornellappdev.score.theme.saturatedGreen -import java.util.Date -import java.util.Locale @Composable fun GameCard( @@ -94,7 +88,8 @@ fun GameCard( ) ) } - ).clickable { onClick(false) } + ) + .clickable { onClick(false) } ) { Column( modifier = Modifier @@ -107,7 +102,8 @@ fun GameCard( modifier = Modifier.fillMaxWidth() ) { Row( - verticalAlignment = Alignment.CenterVertically, modifier = Modifier.widthIn(0.dp, 250.dp) + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.widthIn(0.dp, 250.dp) ) { AsyncImage( model = teamLogo, @@ -209,9 +205,9 @@ fun GameCard( } } -@Preview(showBackground = true) +@Preview @Composable -private fun GameCardPreview() { +private fun GameCardPreview() = ScorePreview { Column { GameCard( teamLogo = "https://cornellbigred.com/images/logos/penn_200x200.png?width=80&height=80&mode=max", //painterResource(id = R.drawable.penn_logo), diff --git a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt index a9a924f..3371ed4 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameDetailsLoadingScreen.kt @@ -102,6 +102,6 @@ fun GameDetailsLoadingScreen( @Preview @Composable -private fun GameDetailsLoadingStatePreview() = ScorePreview{ +private fun GameDetailsLoadingStatePreview() = ScorePreview { GameDetailsLoadingScreen() } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/GameScoreHeader.kt b/app/src/main/java/com/cornellappdev/score/components/GameScoreHeader.kt index 5c7cf90..898c5e7 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GameScoreHeader.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GameScoreHeader.kt @@ -94,7 +94,7 @@ fun GameScoreHeader( @Preview @Composable -private fun GameScoreHeaderPreview() { +private fun GameScoreHeaderPreview() = ScorePreview { GameScoreHeader( leftTeamLogo = painterResource(R.drawable.cornell_logo), rightTeamLogo = painterResource(R.drawable.penn_logo), diff --git a/app/src/main/java/com/cornellappdev/score/components/GamesCarousel.kt b/app/src/main/java/com/cornellappdev/score/components/GamesCarousel.kt index d998174..9490152 100644 --- a/app/src/main/java/com/cornellappdev/score/components/GamesCarousel.kt +++ b/app/src/main/java/com/cornellappdev/score/components/GamesCarousel.kt @@ -27,6 +27,7 @@ import com.cornellappdev.score.theme.CrimsonPrimary import com.cornellappdev.score.theme.GrayLight import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.Style.heading1 +import com.cornellappdev.score.theme.White import com.cornellappdev.score.util.gameList @Composable @@ -106,8 +107,8 @@ fun GamesCarousel( } } -@Preview(showBackground = true, widthDp = 360) @Composable -private fun GamesCarouselPreview() { +@Preview +private fun GamesCarouselPreview() = ScorePreview { GamesCarousel(gameList, GamesCarouselVariant.UPCOMING) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt index 39b6e22..52225f7 100644 --- a/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/components/LoadingScreen.kt @@ -19,9 +19,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.theme.GrayStroke -import com.cornellappdev.score.theme.Style.heading1 import com.cornellappdev.score.theme.LocalInfiniteLoading import com.cornellappdev.score.theme.Stroke +import com.cornellappdev.score.theme.Style.heading1 import com.cornellappdev.score.theme.Wash import com.cornellappdev.score.util.interpolateColorHSV @@ -122,7 +122,7 @@ private fun LoadingFilter() { @Preview @Composable -private fun LoadingFilterPreview() = ScorePreview{ +private fun LoadingFilterPreview() = ScorePreview { LoadingFilter() } diff --git a/app/src/main/java/com/cornellappdev/score/components/NavigationHeader.kt b/app/src/main/java/com/cornellappdev/score/components/NavigationHeader.kt index 96bc2f6..1022b17 100644 --- a/app/src/main/java/com/cornellappdev/score/components/NavigationHeader.kt +++ b/app/src/main/java/com/cornellappdev/score/components/NavigationHeader.kt @@ -1,19 +1,11 @@ package com.cornellappdev.score.components -import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text @@ -22,47 +14,47 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.R -import com.cornellappdev.score.theme.AmbientColor -import com.cornellappdev.score.theme.CrimsonPrimary -import com.cornellappdev.score.theme.GrayLight -import com.cornellappdev.score.theme.SpotColor -import com.cornellappdev.score.theme.Style.bodyMedium import com.cornellappdev.score.theme.Style.heading2 -import com.cornellappdev.score.theme.White @Composable fun NavigationHeader(title: String, onBackPressed: () -> Unit) { - Box(modifier = Modifier - .shadow(elevation=8.dp, clip = false, spotColor = Color.Black.copy(0.05f)) - .background(Color.White)) { - Box(modifier = Modifier - .padding(start=24.dp, top=56.dp, bottom=12.dp, end=24.dp) - .background(Color.White) - .fillMaxWidth() - .height(27.dp)) { - IconButton(onClick = onBackPressed) { - Icon( - painter = painterResource(id = R.drawable.ic_left_arrowhead), - contentDescription = "Back button", - modifier = Modifier - .width(24.dp) - .height(24.dp), - ) - } - Text(text = title, modifier = Modifier.align(Alignment.Center), style = heading2, color = Color.Black) - } - } + Box( + modifier = Modifier + .shadow(elevation = 8.dp, clip = false, spotColor = Color.Black.copy(0.05f)) + .background(Color.White) + ) { + Box( + modifier = Modifier + .padding(start = 24.dp, top = 56.dp, bottom = 12.dp, end = 24.dp) + .background(Color.White) + .fillMaxWidth() + .height(27.dp) + ) { + IconButton(onClick = onBackPressed) { + Icon( + painter = painterResource(id = R.drawable.ic_left_arrowhead), + contentDescription = "Back button", + modifier = Modifier + .width(24.dp) + .height(24.dp), + ) + } + Text( + text = title, + modifier = Modifier.align(Alignment.Center), + style = heading2, + color = Color.Black + ) + } + } } @Preview @Composable -private fun NavigationHeaderPreview() { - NavigationHeader("Game Details", {}) +private fun NavigationHeaderPreview() = ScorePreview { + NavigationHeader("Game Details", {}) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/components/PastGameCard.kt b/app/src/main/java/com/cornellappdev/score/components/PastGameCard.kt index a3c5c66..fcc8506 100644 --- a/app/src/main/java/com/cornellappdev/score/components/PastGameCard.kt +++ b/app/src/main/java/com/cornellappdev/score/components/PastGameCard.kt @@ -3,7 +3,16 @@ package com.cornellappdev.score.components import androidx.compose.foundation.Image import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults @@ -188,9 +197,9 @@ private fun TeamScore( } } -@Preview(showBackground = true) +@Preview @Composable -private fun PastGameCardPreview() { +private fun PastGameCardPreview() = ScorePreview { val gameCard = GameCardData( teamLogo = "https://cornellbigred.com/images/logos/penn_200x200.png?width=80&height=80&mode=max", team = "University of Pennsylvania", diff --git a/app/src/main/java/com/cornellappdev/score/components/ScoreBox.kt b/app/src/main/java/com/cornellappdev/score/components/ScoreBox.kt index 81c073c..3cab34a 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ScoreBox.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ScoreBox.kt @@ -1,9 +1,14 @@ package com.cornellappdev.score.components import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* +import androidx.compose.material3.Divider +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -17,10 +22,8 @@ import com.cornellappdev.score.model.TeamScore import com.cornellappdev.score.theme.CrimsonPrimary import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.Style.bodyNormal -import com.cornellappdev.score.theme.Style.heading6 import com.cornellappdev.score.theme.Style.metricNormal import com.cornellappdev.score.theme.Style.metricSemibold -import com.cornellappdev.score.theme.Style.scoreText import com.cornellappdev.score.theme.saturatedGreen import com.cornellappdev.score.util.emptyGameData import com.cornellappdev.score.util.gameData @@ -82,6 +85,7 @@ fun BoxScore(gameData: GameData) { ) } } + @Composable fun TeamScoreRow(teamScore: TeamScore, totalTextColor: Color) { val showEmpty = teamScore.scoresByPeriod.isEmpty() @@ -132,14 +136,14 @@ fun TeamScoreRow(teamScore: TeamScore, totalTextColor: Color) { } } -@Preview(showBackground = true) +@Preview @Composable -private fun PreviewBoxScore() { +private fun PreviewBoxScore() = ScorePreview { BoxScore(gameData = gameData) } -@Preview(showBackground = true) +@Preview @Composable -private fun PreviewBoxScoreEmpty() { +private fun PreviewBoxScoreEmpty() = ScorePreview { BoxScore(gameData = emptyGameData()) } diff --git a/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt index 1593a11..51d350f 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ScorePreview.kt @@ -14,11 +14,12 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.cornellappdev.score.theme.LocalInfiniteLoading +import com.cornellappdev.score.theme.White @Composable fun ScorePreview( padding: Dp = 0.dp, - backgroundColor: Color = Color.White, + backgroundColor: Color = White, content: @Composable () -> Unit ) { val transition = rememberInfiniteTransition() diff --git a/app/src/main/java/com/cornellappdev/score/components/ScoreSummary.kt b/app/src/main/java/com/cornellappdev/score/components/ScoreSummary.kt index 73d1f7e..6c4218e 100644 --- a/app/src/main/java/com/cornellappdev/score/components/ScoreSummary.kt +++ b/app/src/main/java/com/cornellappdev/score/components/ScoreSummary.kt @@ -13,15 +13,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.cornellappdev.score.components.ScorePreview import com.cornellappdev.score.model.ScoreEvent import com.cornellappdev.score.theme.GrayPrimary import com.cornellappdev.score.theme.Style.bodyMedium import com.cornellappdev.score.theme.Style.bodyNormal -import com.cornellappdev.score.theme.Style.heading5 import com.cornellappdev.score.theme.Style.metricNormal import com.cornellappdev.score.theme.Style.metricSemibold import com.cornellappdev.score.util.scoreEvents1 @@ -112,8 +111,8 @@ fun ScoreEventItem(event: ScoreEvent) { } } -@Preview(showBackground = true) +@Preview @Composable -private fun PreviewScoringSummary() { +private fun PreviewScoringSummary() = ScorePreview { ScoringSummary(scoreEvents = scoreEvents1) } diff --git a/app/src/main/java/com/cornellappdev/score/components/SportSelectorHeader.kt b/app/src/main/java/com/cornellappdev/score/components/SportSelectorHeader.kt index c0b9afb..313ccd9 100644 --- a/app/src/main/java/com/cornellappdev/score/components/SportSelectorHeader.kt +++ b/app/src/main/java/com/cornellappdev/score/components/SportSelectorHeader.kt @@ -175,7 +175,7 @@ fun SportSelector( @Preview @Composable -private fun PreviewSportSelectorHeader() { +private fun PreviewSportSelectorHeader() = ScorePreview { var selectedOption by remember { mutableStateOf(GenderDivision.ALL) } var selectedSport: SportSelection by remember { mutableStateOf(SportSelection.All) } diff --git a/app/src/main/java/com/cornellappdev/score/components/TimeUntilStartCard.kt b/app/src/main/java/com/cornellappdev/score/components/TimeUntilStartCard.kt index b193e35..7aef44d 100644 --- a/app/src/main/java/com/cornellappdev/score/components/TimeUntilStartCard.kt +++ b/app/src/main/java/com/cornellappdev/score/components/TimeUntilStartCard.kt @@ -70,6 +70,6 @@ fun TimeUntilStartCard(days: Int, hours: Int) { @Preview @Composable -private fun TimeUntilStartCardPreview() { +private fun TimeUntilStartCardPreview() = ScorePreview { TimeUntilStartCard(2, 0) } \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/screen/GameDetailsScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/GameDetailsScreen.kt index e27d4e9..4444fdc 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/GameDetailsScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/GameDetailsScreen.kt @@ -2,7 +2,6 @@ package com.cornellappdev.score.screen import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -23,6 +22,7 @@ import com.cornellappdev.score.R import com.cornellappdev.score.components.ButtonPrimary import com.cornellappdev.score.components.GameScoreHeader import com.cornellappdev.score.components.NavigationHeader +import com.cornellappdev.score.components.ScorePreview import com.cornellappdev.score.components.TimeUntilStartCard import com.cornellappdev.score.theme.GrayMedium import com.cornellappdev.score.theme.GrayPrimary @@ -33,7 +33,12 @@ import com.cornellappdev.score.theme.White @Composable fun GameDetailsScreen(gameId: String = "", onBackArrow: () -> Unit = {}) { - Column(modifier = Modifier.background(White).fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) { + Column( + modifier = Modifier + .background(White) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { // TODO: add navigation NavigationHeader(title = "Game Details", onBackArrow) GameScoreHeader( @@ -94,7 +99,7 @@ fun GameDetailsScreen(gameId: String = "", onBackArrow: () -> Unit = {}) { @Preview @Composable -private fun GameDetailsScreenPreview() { +private fun GameDetailsScreenPreview() = ScorePreview { GameDetailsScreen() // import androidx.compose.ui.tooling.preview.Preview // import androidx.compose.ui.unit.dp diff --git a/app/src/main/java/com/cornellappdev/score/screen/GameScoreSummaryScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/GameScoreSummaryScreen.kt index a34d466..09bad26 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/GameScoreSummaryScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/GameScoreSummaryScreen.kt @@ -3,6 +3,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -22,19 +23,22 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.cornellappdev.score.components.NavigationHeader +import com.cornellappdev.score.components.ScorePreview import com.cornellappdev.score.model.ScoreEvent import com.cornellappdev.score.theme.Style.bodyNormal import com.cornellappdev.score.theme.Style.spanBodyNormal +import com.cornellappdev.score.theme.White import com.cornellappdev.score.util.scoreEvents2 -import androidx.compose.foundation.layout.fillMaxSize @Composable fun GameScoreSummaryScreenDetail(scoreEvents: List) { - Column(modifier = Modifier.fillMaxSize()){ + Column(modifier = Modifier.fillMaxSize()) { // TODO: add navigation NavigationHeader(title = "Scoring Summary", {}) LazyColumn( - modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp, vertical = 8.dp) + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp, vertical = 8.dp) ) { items(scoreEvents.size) { event -> ScoreEventItemDetailed(event = scoreEvents[event]) @@ -74,24 +78,24 @@ fun ScoreEventItemDetailed(event: ScoreEvent) { Text( textAlign = TextAlign.Center, text = - buildAnnotatedString { - withStyle( - style = spanBodyNormal - ) { - append("${event.time} - ${event.quarter.replace(" Quarter", "")}\n") - } - withStyle( - style = homeScoreStyle - ) { - append(event.homeScore) - } - withStyle(style = spanBodyNormal) { - append(" - ") - } - withStyle(style = awayScoreStyle) { - append(event.awayScore) + buildAnnotatedString { + withStyle( + style = spanBodyNormal + ) { + append("${event.time} - ${event.quarter.replace(" Quarter", "")}\n") + } + withStyle( + style = homeScoreStyle + ) { + append(event.homeScore) + } + withStyle(style = spanBodyNormal) { + append(" - ") + } + withStyle(style = awayScoreStyle) { + append(event.awayScore) + } } - } ) } Spacer(modifier = Modifier.width(16.dp)) @@ -105,8 +109,8 @@ fun ScoreEventItemDetailed(event: ScoreEvent) { } -@Preview(showBackground = true) +@Preview @Composable -private fun PreviewScoringDetailsScreen() { +private fun PreviewScoringDetailsScreen() = ScorePreview { GameScoreSummaryScreenDetail(scoreEvents = scoreEvents2) } diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index 32185b5..599e798 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -21,9 +21,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.cornellappdev.score.components.ErrorState -import com.cornellappdev.score.components.LoadingScreen -import com.cornellappdev.score.components.GamesCarousel import com.cornellappdev.score.components.GameCard +import com.cornellappdev.score.components.GamesCarousel +import com.cornellappdev.score.components.LoadingScreen +import com.cornellappdev.score.components.ScorePreview import com.cornellappdev.score.components.SportSelectorHeader import com.cornellappdev.score.model.ApiResponse import com.cornellappdev.score.model.GamesCarouselVariant @@ -123,7 +124,7 @@ private fun HomeContent( @Preview @Composable -private fun HomeScreenPreview() { +private fun HomeScreenPreview() = ScorePreview { Column( modifier = Modifier .fillMaxSize() diff --git a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt index 8f153bd..8d36258 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt @@ -1,7 +1,7 @@ package com.cornellappdev.score.screen -import androidx.compose.foundation.background import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -22,6 +22,7 @@ import com.cornellappdev.score.components.ErrorState import com.cornellappdev.score.components.GamesCarousel import com.cornellappdev.score.components.LoadingScreen import com.cornellappdev.score.components.PastGameCard +import com.cornellappdev.score.components.ScorePreview import com.cornellappdev.score.components.SportSelectorHeader import com.cornellappdev.score.model.ApiResponse import com.cornellappdev.score.model.GamesCarouselVariant @@ -114,7 +115,7 @@ private fun PastGamesContent( @Composable @Preview -private fun PastGamesPreview() { +private fun PastGamesPreview() = ScorePreview { PastGamesContent( uiState = PastGamesUiState( selectedGender = GenderDivision.ALL,