Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions app/src/main/java/com/cornellappdev/score/components/ErrorState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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(
onRefresh: () -> Unit,
message: String
) {
Column(
modifier = Modifier
.fillMaxWidth()
.height(422.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant parameter here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i made a column for the feedback icon + text and nested that + the button within the main column, so i think both of these are necessary

) {
Image(
painter = painterResource(R.drawable.ic_feedback),
contentDescription = "feedback bubble"
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = message,
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 = onRefresh
) {
Row() {
Image(
painter = painterResource(R.drawable.ic_cached),
contentDescription = "cached"
)
Text("Try again")
}
}
}
}

@Preview
@Composable
private fun ErrorStatePreview() {
ErrorState({}, "Oops! Failed to load.")
}
Original file line number Diff line number Diff line change
@@ -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()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So because you used a Composition local provider, this breaks your previews since we didn't provide the value here. Could you make a custom preview function ScorePreview that is sort of like ResellPreview, and then provide the value through a custom ScoreTheme function? Sorry to have you just using the Resell code so much but I do think it's the best solution. I don't want you to just feel like you're copying and pasting code and not understanding why so please ask questions if you have them! Composition locals are a tricky topic.

}
126 changes: 126 additions & 0 deletions app/src/main/java/com/cornellappdev/score/components/LoadingState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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
import com.cornellappdev.score.theme.GrayStroke
import com.cornellappdev.score.theme.Style.heading1

@Composable
fun LoadingState(
topHeader: String,
bottomHeader: String
) {
Column(
modifier = Modifier.fillMaxSize()
) {
Column(
modifier = Modifier.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = topHeader,
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 = bottomHeader,
style = heading1,
color = GrayStroke,
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Start)
)
Spacer(modifier = Modifier.height(16.dp))
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() {
LoadingState("Loading Upcoming...", "Loading Schedules...")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.cornellappdev.score.components

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
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.unit.Dp
import com.cornellappdev.score.theme.GrayStroke

@Composable
fun LoadingStateBox(cornerRoundness: Int, height: Dp) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think it's better to just expose a Modifier parameter here instead of 2 separate parameters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the cornerRoundness is nested within Modifier.background and I'm passing in the same color parameter each time for Modifier.background, is it okay if i keep the cornerRoundness so I can pass it in and use a modifier parameter for the height/width?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i also want to have the default width be the maxWidth and I don't have a default value for the height so maybe it would be better to leave height as it's own parameter too?

Box(
modifier = Modifier
.background(color = GrayStroke, shape = RoundedCornerShape(cornerRoundness))
.height(height)
.fillMaxWidth()
)
}
Loading