Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import com.cornellappdev.uplift.ui.screens.gyms.GymDetailScreen
import com.cornellappdev.uplift.ui.screens.gyms.HomeScreen
import com.cornellappdev.uplift.ui.screens.onboarding.ProfileCreationScreen
import com.cornellappdev.uplift.ui.screens.onboarding.SignInPromptScreen
import com.cornellappdev.uplift.ui.screens.profile.GuestProfileScreen
import com.cornellappdev.uplift.ui.screens.profile.ProfileScreen
import com.cornellappdev.uplift.ui.screens.profile.SettingsScreen
import com.cornellappdev.uplift.ui.screens.profile.WorkoutHistoryScreen
Expand Down Expand Up @@ -118,8 +119,14 @@ fun MainNavigationWrapper(

//TODO: Try to consolidate launched effects into one with consumeIn function that takes in coroutine scope
LaunchedEffect(rootNavigationUiState.navEvent) {
rootNavigationUiState.navEvent?.consumeSuspend {
navController.navigate(it)
rootNavigationUiState.navEvent?.consumeSuspend { route ->
navController.navigate(route) {
if (route == UpliftRootRoute.Home) {
// Finish skip/login/onboarding without leaving those screens on Back.
popUpTo(0)
launchSingleTop = true
}
}
}
}
LaunchedEffect(rootNavigationUiState.popBackStack) {
Expand Down Expand Up @@ -258,7 +265,11 @@ fun MainNavigationWrapper(
CapacityReminderScreen()
}
composable<UpliftRootRoute.Profile> {
ProfileScreen()
if (isLoggedIn) {
ProfileScreen()
} else {
GuestProfileScreen()
}
}
composable<UpliftRootRoute.Reminders> {
MainReminderScreen()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fun UpliftButton(
fontSize = fontSize.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
modifier = modifier.wrapContentSize()
modifier = Modifier.wrapContentSize()
)
}
}
Expand All @@ -100,4 +100,4 @@ fun UpliftButton(
@Composable
fun UpliftButtonPreview() {
UpliftButton(onClick = { /*TODO*/ })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.credentials.Credential
Expand All @@ -16,7 +17,10 @@ import com.cornellappdev.uplift.ui.components.general.UpliftButton
import kotlinx.coroutines.launch

@Composable
fun LogInButton(onRequestResult: (Credential) -> Unit) {
fun LogInButton(
onRequestResult: (Credential) -> Unit,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
UpliftButton(
Expand All @@ -32,7 +36,8 @@ fun LogInButton(onRequestResult: (Credential) -> Unit) {
width = 144.dp,
height = 44.dp,
fontSize = 16f,
elevation = 2.dp
elevation = 2.dp,
modifier = modifier
)
}

Expand Down Expand Up @@ -60,4 +65,4 @@ private suspend fun launchCredentialManagerButtonUI(
Log.e("CredentialManager", e.message.orEmpty(), e)
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.cornellappdev.uplift.ui.screens.profile

import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
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.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
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 androidx.compose.ui.unit.sp
import androidx.credentials.Credential
import androidx.hilt.navigation.compose.hiltViewModel
import com.cornellappdev.uplift.R
import com.cornellappdev.uplift.ui.components.onboarding.auth.LogInButton
import com.cornellappdev.uplift.ui.viewmodels.onboarding.LoginViewModel
import com.cornellappdev.uplift.util.LIGHT_YELLOW
import com.cornellappdev.uplift.util.PRIMARY_BLACK
import com.cornellappdev.uplift.util.montserratFamily

@Composable
fun GuestProfileScreen(
loginViewModel: LoginViewModel = hiltViewModel(),
) {
GuestProfileScreenContent(loginViewModel::onSignInWithGoogle)
}

@Composable
private fun GuestProfileScreenContent(onSignIn: (Credential) -> Unit) {
BoxWithConstraints(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.clipToBounds()
) {
val headerScale = (maxHeight.value / 769f).coerceIn(0.65f, 1.2f)
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Column(
modifier = Modifier
.fillMaxWidth()
.height(375.dp * headerScale)
.drawBehind {
drawCircle(
color = LIGHT_YELLOW,
radius = 353.5.dp.toPx() * headerScale,
center = Offset(size.width * 101.5f / 393f, 4.5.dp.toPx() * headerScale)
)
},
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(Modifier.height(136.dp * headerScale))
Image(
painter = painterResource(R.drawable.ic_main_logo),
contentDescription = "Uplift logo",
modifier = Modifier
.width(207.dp * headerScale)
.height(183.dp * headerScale)
)
}
Spacer(Modifier.height(24.dp))
Text(
text = "Create your Uplift profile.",
modifier = Modifier.padding(horizontal = 16.dp),
fontFamily = montserratFamily,
fontWeight = FontWeight.Bold,
fontSize = 24.sp,
lineHeight = 30.sp,
color = PRIMARY_BLACK,
textAlign = TextAlign.Center
)
Spacer(Modifier.height(24.dp))
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
GuestProfileBenefit(R.drawable.guest_profile_goal, "Create fitness goals")
GuestProfileBenefit(R.drawable.gym_simple, "Track fitness progress")
GuestProfileBenefit(R.drawable.history, "View workout history")
}
Spacer(Modifier.height(48.dp))
LogInButton(
onRequestResult = onSignIn,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
)
Spacer(Modifier.height(32.dp))
}
}
}

@Composable
private fun GuestProfileBenefit(@DrawableRes icon: Int, text: String) {
Row(
modifier = Modifier
.width(240.dp)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Image(
painter = painterResource(icon),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Text(
text = text,
fontFamily = montserratFamily,
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
lineHeight = 16.sp,
color = PRIMARY_BLACK.copy(alpha = 0.9f)
)
}
}

@Preview(showBackground = true, widthDp = 393, heightDp = 769)
@Composable
private fun GuestProfilePreview() {
GuestProfileScreenContent {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ class RootNavigationViewModel @Inject constructor(
val popBackStack: UIEvent<Unit>? = null,
val navigateUp: UIEvent<Unit>? = null,
val startDestination: UpliftRootRoute = if (ONBOARDING_FLAG) UpliftRootRoute.Onboarding else UpliftRootRoute.Home
)
) {
internal fun withSession(loggedIn: Boolean, destination: UpliftRootRoute): RootNavigationUiState {
val shouldNavigate = destination != startDestination || loggedIn != isLoggedIn
return copy(
isLoggedIn = loggedIn,
startDestination = destination,
navEvent = if (shouldNavigate) UIEvent(destination) else navEvent
)
}
}

init {

Expand All @@ -60,25 +69,16 @@ class RootNavigationViewModel @Inject constructor(

viewModelScope.launch {
sessionManager.isLoggedIn.collect { loggedIn ->
applyMutation {
copy(isLoggedIn = loggedIn)
}

val hasSkipped = userInfoRepository.getSkipFromDataStore()
val shouldShowHome = loggedIn || hasSkipped || !ONBOARDING_FLAG
val newRoute = if (shouldShowHome) UpliftRootRoute.Home else UpliftRootRoute.Onboarding

applyMutation {
// Only attach a navEvent if we are actually changing the destination compared to what was set during initialization.
val shouldNav = newRoute != startDestination || loggedIn != isLoggedIn

copy(
isLoggedIn = loggedIn,
startDestination = newRoute,
navEvent = if (shouldNav) UIEvent(newRoute) else navEvent
)
// Compare against the previous session before updating it. Guest login
// must finish onboarding even when Home is already the start destination.
withSession(loggedIn, newRoute)
}
}
}
}
}
}
21 changes: 21 additions & 0 deletions app/src/main/res/drawable/guest_profile_goal.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group android:translateX="1" android:translateY="5">
<path
android:pathData="M11,1C13.655,1 16.201,2.054 18.078,3.932C19.848,5.701 20.886,8.066 20.999,10.555C21.011,10.806 20.806,11.01 20.555,11.01C20.303,11.01 20.101,10.806 20.088,10.555C19.976,8.307 19.034,6.174 17.434,4.575C15.728,2.869 13.413,1.91 11,1.91C8.587,1.91 6.272,2.869 4.565,4.575C2.966,6.174 2.024,8.307 1.912,10.555C1.899,10.806 1.697,11.01 1.445,11.01C1.194,11.01 0.989,10.806 1.001,10.555C1.114,8.066 2.152,5.701 3.922,3.932C5.799,2.055 8.345,1 11,1ZM11,0C8.08,0 5.279,1.16 3.215,3.225L3.215,3.225C1.268,5.171 0.126,7.771 0.002,10.509C0.001,10.528 0,10.546 0,10.564L0,10.564L0,10.591L0,10.591C0.007,11.401 0.68,12.01 1.445,12.01C2.261,12.01 2.873,11.356 2.91,10.605C3.011,8.604 3.849,6.706 5.272,5.282L5.272,5.282L5.272,5.282C6.791,3.763 8.852,2.91 11,2.91C13.148,2.91 15.208,3.763 16.727,5.282L16.727,5.282L16.727,5.282C18.151,6.706 18.989,8.604 19.089,10.605C19.127,11.356 19.739,12.01 20.555,12.01C21.346,12.01 22.037,11.36 21.998,10.509C21.874,7.771 20.732,5.171 18.785,3.225L18.785,3.225C16.72,1.16 13.92,0 11,0Z"
android:fillColor="#222222"/>
<path
android:pathData="M17.835,4.185m-1.525,0a1.525,1.525 0,1 1,3.05 0a1.525,1.525 0,1 1,-3.05 0"
android:strokeWidth="1.5"
android:fillColor="#ffffff"
android:strokeColor="#222222"/>
<path
android:strokeWidth="1"
android:pathData="M11.334,9.171L15.448,6.413C15.457,6.407 15.467,6.417 15.462,6.426L12.917,10.676C12.588,11.225 11.835,11.328 11.37,10.887L11.202,10.727C10.738,10.286 10.802,9.528 11.334,9.171Z"
android:fillColor="#222222"
android:strokeColor="#222222"/>
</group>
</vector>
Binary file removed app/src/main/res/drawable/ic_main_logo.png
Binary file not shown.
14 changes: 14 additions & 0 deletions app/src/main/res/drawable/ic_main_logo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="206.95dp"
android:height="183dp"
android:viewportWidth="206.95"
android:viewportHeight="183">
<path
android:pathData="M104.7,166.48C145.96,166.48 179.4,132.97 179.4,91.62C179.4,50.28 145.96,16.77 104.7,16.77C63.44,16.77 30,50.28 30,91.62C30,132.97 63.44,166.48 104.7,166.48Z"
android:fillColor="#F8E71C"
android:fillType="evenOdd"/>
<path
android:pathData="M109.96,32.7C109.96,27.04 113.36,21.94 118.62,19.86C135.1,13.35 170.51,0 183.75,0C201.26,0 205.84,18.35 205.84,18.35C205.84,18.35 208.34,88.81 205.84,97.99C204.9,101.45 201.51,106.17 197.67,110.69C189.1,120.77 177.34,127.4 164.9,131.88L142.06,140.1L141.1,165.79L109.96,183V32.7ZM64.56,43.75L97.36,26.1V144.87C97.36,150.56 93.94,155.67 88.65,157.75C74.04,163.5 45.41,174.35 37.47,174.35C26.66,174.35 22.88,173.93 15.79,169.77C4.72,163.25 -0.29,150.24 0.01,137.4L1.62,69.28L31.63,54.49V140.99C31.63,140.99 34.92,145.54 42.88,143.53C50.85,141.51 64.56,132.66 64.56,132.66V43.75ZM142.06,43.36V108.41C142.06,108.41 157.07,105.91 169.57,95.07C182.08,84.23 176.66,40.45 174.58,35.86C172.49,31.27 142.06,43.36 142.06,43.36Z"
android:fillColor="#222222"
android:fillType="evenOdd"/>
</vector>