Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Hustle"
android:theme="@style/Theme.Hustle.Starting"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.Hustle">
android:theme="@style/Theme.Hustle.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/cornellappdev/hustle/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class MainActivity : ComponentActivity() {

enableEdgeToEdge()
setContent {
HustleTheme {
HustleTheme(dynamicColor = false) {
val rootUiState = rootViewModel.collectUiStateValue()
if (!rootUiState.isLoading) {
HustleApp(isSignedIn = rootUiState.isSignedIn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,10 @@ class HustleFirebaseMessagingService : FirebaseMessagingService() {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

// TODO: Replace with actual app icon
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.drawable.ic_google)
.setSmallIcon(R.drawable.ic_hustle_logo)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.cornellappdev.hustle.ui.components.onboarding

import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
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.hustle.ui.theme.HustleColors
import com.cornellappdev.hustle.ui.theme.HustleSpacing
import com.cornellappdev.hustle.ui.theme.HustleTheme

@Composable
fun SignInButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
isLoading: Boolean = false
) {
Button(
onClick = onClick,
enabled = !isLoading,
modifier = modifier.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(
containerColor = HustleColors.accentGreen,
contentColor = HustleColors.hustleGreen,
disabledContainerColor = HustleColors.accentGreen,
disabledContentColor = HustleColors.hustleGreen
),
contentPadding = PaddingValues(
vertical = HustleSpacing.medium
),
shape = RoundedCornerShape(15.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(HustleSpacing.small),
modifier = Modifier.animateContentSize()
) {
if (isLoading) {
CircularProgressIndicator(
color = HustleColors.hustleGreen,
modifier = Modifier.size(24.dp)
)
}
Comment on lines +50 to +55

Choose a reason for hiding this comment

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

Nit: could we wrap this in animateContentSize to make the whole experience a bit cleaner

Copy link
Member Author

Choose a reason for hiding this comment

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

Will look into

Copy link
Member Author

Choose a reason for hiding this comment

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

Added to the row modifier

Text(
text = if (isLoading) "Signing in..." else "Log in with NetID",
style = MaterialTheme.typography.titleLarge
)
}

}
}

@Preview(showBackground = true)
@Composable
private fun SignInButtonPreview() {
HustleTheme(dynamicColor = false) {
SignInButton(onClick = {}, isLoading = true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.cornellappdev.hustle.ui.navigation.navgraphs.homeNavGraph
import com.cornellappdev.hustle.ui.navigation.navgraphs.messagesNavGraph
import com.cornellappdev.hustle.ui.navigation.navgraphs.onboardingNavGraph
import com.cornellappdev.hustle.ui.navigation.navgraphs.profileNavGraph
import com.cornellappdev.hustle.ui.theme.HustleColors

@Composable
fun HustleNavigation(
Expand All @@ -23,7 +24,8 @@ fun HustleNavigation(
if (isSignedIn) {
BottomNavigationBar(navController = navController)
}
}
},
containerColor = if (!isSignedIn) HustleColors.hustleGreen else HustleColors.white
) { innerPadding ->
NavHost(
navController = navController,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
package com.cornellappdev.hustle.ui.screens.onboarding

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.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.cornellappdev.hustle.R
import com.cornellappdev.hustle.ui.components.general.ErrorMessage
import com.cornellappdev.hustle.ui.components.onboarding.GoogleSignInButton
import com.cornellappdev.hustle.ui.components.onboarding.SignInButton
import com.cornellappdev.hustle.ui.theme.HustleColors
import com.cornellappdev.hustle.ui.theme.HustleSpacing
import com.cornellappdev.hustle.ui.theme.HustleTheme
import com.cornellappdev.hustle.ui.theme.InstrumentSans
import com.cornellappdev.hustle.ui.viewmodels.ActionState
import com.cornellappdev.hustle.ui.viewmodels.onboarding.SignInScreenViewModel

Expand Down Expand Up @@ -49,13 +68,23 @@ private fun SignInScreenContent(
onDismissError: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.fillMaxSize()) {
Box(
modifier = modifier
.fillMaxSize()
.background(HustleColors.hustleGreen)
.padding(
horizontal = HustleSpacing.leftRightMargin
)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.spacedBy(
89.dp, alignment = Alignment.CenterVertically
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

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

The hardcoded spacing value of 89.dp should use a constant from HustleSpacing for consistency with the design system.

Suggested change
89.dp, alignment = Alignment.CenterVertically
HustleSpacing.signInScreenVerticalSpacing, alignment = Alignment.CenterVertically

Copilot uses AI. Check for mistakes.
),
modifier = Modifier.fillMaxSize()
) {
GoogleSignInButton(
WelcomeHeader()
SignInButton(
onClick = onGoogleSignInButtonClick, isLoading = isSignInLoading
)
}
Expand All @@ -69,6 +98,59 @@ private fun SignInScreenContent(
}
}

@Composable
private fun WelcomeHeader() {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(HustleSpacing.medium)
) {
Icon(
painter = painterResource(id = R.drawable.ic_hustle_logo),
contentDescription = "Hustle Logo",
tint = Color.Unspecified

Choose a reason for hiding this comment

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

Is unspecified intentional? Why is it needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think Compose tints the icon another color without it, so this makes sure it keeps the original color

)
WelcomeText()
}
}

@Composable
private fun WelcomeText() {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(HustleSpacing.extraSmall)
) {
Text(
buildAnnotatedString {
withStyle(
style = SpanStyle(
color = HustleColors.white,
fontFamily = InstrumentSans,
fontSize = 36.sp,
)
) {
append("Welcome to ")
}
withStyle(
style = SpanStyle(
color = HustleColors.white,
fontFamily = InstrumentSans,
fontSize = 36.sp,
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Italic
)
) {
append("Hustle")
}
}
)
Text(
text = "Browse. Buy. Book.",
color = HustleColors.white,
style = MaterialTheme.typography.headlineMedium
)
}
}

class SignInErrorMessageProvider : PreviewParameterProvider<String?> {
override val values = sequenceOf(
null,
Expand All @@ -81,9 +163,11 @@ class SignInErrorMessageProvider : PreviewParameterProvider<String?> {
private fun SignInScreenPreview(
@PreviewParameter(SignInErrorMessageProvider::class) errorMessage: String?
) {
SignInScreenContent(
onGoogleSignInButtonClick = {},
isSignInLoading = false,
errorMessage = errorMessage,
onDismissError = {})
HustleTheme(dynamicColor = false) {
SignInScreenContent(
onGoogleSignInButtonClick = {},
isSignInLoading = false,
errorMessage = errorMessage,
onDismissError = {})
}
}
19 changes: 12 additions & 7 deletions app/src/main/java/com/cornellappdev/hustle/ui/theme/Color.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package com.cornellappdev.hustle.ui.theme

import androidx.compose.ui.graphics.Color

val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
object HustleColors {

Choose a reason for hiding this comment

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

I feel like we should be getting these based on the theme instead, so this way it's easier to support dark theme in the future

Copy link
Member Author

Choose a reason for hiding this comment

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

Will look into

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe the new commit should have this now. I did need to add the dynamicColor = false to the HustleTheme parameters for the colors to apply properly.

val hustleGreen = Color(0xFF004346)
val accentGreen = Color(0xFFD5EFB4)
val primaryBlack = Color(0xFF000000)
val tertiaryGray = Color(0xFF2D2D2D)
val secondaryGray = Color(0xFF7D8288)
val iconInactive = Color(0xFFBEBEBE)
val stroke = Color(0xFFD6D6D6)
val wash = Color(0xFFF5F5F5)
val tint = Color(0xFFB2B3B6)
val white = Color(0xFFFFFFFF)
}
16 changes: 16 additions & 0 deletions app/src/main/java/com/cornellappdev/hustle/ui/theme/Spacing.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.cornellappdev.hustle.ui.theme

import androidx.compose.ui.unit.dp

object HustleSpacing {
val extraSmall = 8.dp
val small = 12.dp
val medium = 16.dp
val large = 24.dp
val extraLarge = 36.dp
val huge = 64.dp

val topMarginBig = huge
val topMarginNormal = extraLarge
val leftRightMargin = large
}
Loading