From 59156bed9d118b76aedfe77d45b61e087e51d15a Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 21 Mar 2026 01:14:19 -0400 Subject: [PATCH 1/7] Onboarding screen without login interface --- app/build.gradle.kts | 7 +- .../com/cornellappdev/chimes/MainActivity.kt | 3 +- .../chimes/ui/screens/Onboarding.kt | 243 ++++++++++++++++ app/src/main/res/drawable/ic_clock.xml | 16 ++ app/src/main/res/drawable/ic_hour_hand.xml | 12 + app/src/main/res/drawable/ic_logo.xml | 16 ++ app/src/main/res/drawable/ic_minute_hand.xml | 12 + .../res/drawable/ic_onboarding_background.xml | 262 ++++++++++++++++++ gradle.properties | 5 +- gradle/libs.versions.toml | 6 +- 10 files changed, 573 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt create mode 100644 app/src/main/res/drawable/ic_clock.xml create mode 100644 app/src/main/res/drawable/ic_hour_hand.xml create mode 100644 app/src/main/res/drawable/ic_logo.xml create mode 100644 app/src/main/res/drawable/ic_minute_hand.xml create mode 100644 app/src/main/res/drawable/ic_onboarding_background.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ac40860..86c9c8f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,14 +5,12 @@ plugins { android { namespace = "com.cornellappdev.chimes" - compileSdk { - version = release(36) - } + compileSdk = 35 defaultConfig { applicationId = "com.cornellappdev.chimes" minSdk = 24 - targetSdk = 36 + targetSdk = 35 versionCode = 1 versionName = "1.0" @@ -47,6 +45,7 @@ dependencies { implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.material3) implementation(libs.androidx.ui.graphics) + implementation(libs.ui.graphics) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) diff --git a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt index 3588561..3bd32f7 100644 --- a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt +++ b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.cornellappdev.chimes.ui.components.HeaderButton import com.cornellappdev.chimes.ui.screens.HomeScreen +import com.cornellappdev.chimes.ui.screens.Onboarding import com.cornellappdev.chimes.ui.theme.ChimesandroidTheme class MainActivity : ComponentActivity() { @@ -55,7 +56,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { - HomeScreen() + Onboarding() } } } diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt new file mode 100644 index 0000000..4946fcf --- /dev/null +++ b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt @@ -0,0 +1,243 @@ +package com.cornellappdev.chimes.ui.screens + +import android.annotation.SuppressLint +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy +import androidx.compose.ui.graphics.TransformOrigin +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.cornellappdev.chimes.R +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + + +@Composable +fun Onboarding () { + val bgAlpha = remember { Animatable(1f) } + val whiteAlpha = remember { Animatable(0f) } + val logoAlpha = remember { Animatable(0f) } + val logoScale = remember { Animatable(1f) } + val chimesAlpha = remember { Animatable(0f) } + val headerOffsetY = remember { Animatable(0f) } + val loginAlpha = remember { Animatable(0f) } + val minuteHandRotation = remember { Animatable(0f) } + val hourHandRotation = remember { Animatable(0f) } + var handsSpinStarted by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { + delay(300) + + launch { + bgAlpha.animateTo(0f, tween(300, easing = LinearEasing)) + } + + delay(300) + launch { + whiteAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + } + delay(300) + logoAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + + delay(300) + + logoScale.animateTo(0.55f, tween(300, easing = FastOutSlowInEasing)) + handsSpinStarted = true + + + delay(300) + chimesAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + + delay(300) + launch { + headerOffsetY.animateTo(-90f, tween(300, easing = FastOutSlowInEasing)) + } + delay(300) + loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + } + + LaunchedEffect(handsSpinStarted) { + if (!handsSpinStarted) return@LaunchedEffect + + launch { + while (isActive) { + minuteHandRotation.animateTo( + minuteHandRotation.value + 360f, + animationSpec = tween(durationMillis = 2_000, easing = LinearEasing) + ) + } + } + launch { + while (isActive) { + hourHandRotation.animateTo( + hourHandRotation.value + 360f, + animationSpec = tween(durationMillis = 10_000, easing = LinearEasing) + ) + } + } + } + + Box(modifier = Modifier.fillMaxSize().background(Color.White)) { + + Image( + painter = painterResource(id = R.drawable.ic_onboarding_background), + contentDescription = "Onboarding background", + modifier = Modifier + .fillMaxSize() + .alpha(bgAlpha.value), + contentScale = ContentScale.Crop + ) + + + + /* + //with gradient fade + Image( + painter = painterResource(id = R.drawable.ic_onboarding_background), + contentDescription = "Onboarding background", + modifier = Modifier + .fillMaxSize() + .graphicsLayer{ + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent{ + drawContent() + val brush = Brush.verticalGradient( + 0f to Color.White, + bgAlpha.value to Color.Transparent + ) + drawRect(brush = brush, blendMode = BlendMode.DstIn) + }, + contentScale = ContentScale.Crop + ) + + */ + + /* + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .alpha(whiteAlpha.value) + ) + + */ + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Spacer(modifier = Modifier.height(headerOffsetY.value.dp)) + + ClockLogo( + modifier = Modifier + .size((300 * logoScale.value).dp) + .alpha(logoAlpha.value), + minuteHandRotation = minuteHandRotation.value, + hourHandRotation = hourHandRotation.value + ) + + Spacer(modifier = Modifier.height(10.dp)) + + Text( + text = "chimes", + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Medium, + color = Color(0xFFE24B4B) + ), + modifier = Modifier.alpha(chimesAlpha.value), + fontSize = 18.sp + ) + Spacer(modifier = Modifier.height(140.dp)) + } + } +} + +@SuppressLint("UnusedBoxWithConstraintsScope") +@Composable +private fun ClockLogo( + modifier: Modifier = Modifier, + minuteHandRotation: Float, + hourHandRotation: Float +) { + BoxWithConstraints( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + val clockSize = maxWidth * (69f / 118f) + // Adjust these coefficients to make the hands smaller/larger + val minuteHandWidth = maxWidth * 0.21f + val minuteHandHeight = maxWidth * 0.12f + val hourHandWidth = maxWidth * 0.17f + val hourHandHeight = maxWidth * 0.14f + + Image( + painter = painterResource(id = R.drawable.ic_clock), + contentDescription = "Clock base", + contentScale = ContentScale.FillBounds, + modifier = Modifier.size(clockSize) + ) + + Image( + painter = painterResource(id = R.drawable.ic_hour_hand), + contentDescription = "Hour hand", + contentScale = ContentScale.FillBounds, + modifier = Modifier + .size(hourHandWidth, hourHandHeight) + .graphicsLayer { + var value = 11f / 30f + translationX = (0.5f - value) * size.width + translationY = (0.5f - value) * size.height + + rotationZ = hourHandRotation + transformOrigin = TransformOrigin(value, value) + } + ) + + Image( + painter = painterResource(id = R.drawable.ic_minute_hand), + contentDescription = "Minute hand", + contentScale = ContentScale.FillBounds, + modifier = Modifier + .size(minuteHandWidth, minuteHandHeight) + .graphicsLayer { + var xValue = 2.5f/25f + var yValue = 16.5f/25f + + translationX = (0.5f - xValue) * size.width + translationY = (0.5f - yValue) * size.height + + rotationZ = minuteHandRotation + transformOrigin = TransformOrigin(xValue, yValue) + } + ) + } +} diff --git a/app/src/main/res/drawable/ic_clock.xml b/app/src/main/res/drawable/ic_clock.xml new file mode 100644 index 0000000..45922c7 --- /dev/null +++ b/app/src/main/res/drawable/ic_clock.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_hour_hand.xml b/app/src/main/res/drawable/ic_hour_hand.xml new file mode 100644 index 0000000..9546a8f --- /dev/null +++ b/app/src/main/res/drawable/ic_hour_hand.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..36826da --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_minute_hand.xml b/app/src/main/res/drawable/ic_minute_hand.xml new file mode 100644 index 0000000..e1f907d --- /dev/null +++ b/app/src/main/res/drawable/ic_minute_hand.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_onboarding_background.xml b/app/src/main/res/drawable/ic_onboarding_background.xml new file mode 100644 index 0000000..1b65158 --- /dev/null +++ b/app/src/main/res/drawable/ic_onboarding_background.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle.properties b/gradle.properties index 20e2a01..f533532 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,7 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true + +# Disable file system watching to prevent file locking issues on Windows/OneDrive +org.gradle.vfs.watch=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c675daf..a667456 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,9 +11,9 @@ composeBom = "2024.09.00" uiGraphics = "1.10.2" nav3Core = "1.0.1" lifecycleViewmodelNav3 = "2.11.0-alpha01" -kotlinSerialization = "2.2.21" kotlinxSerializationCore = "1.9.0" material3AdaptiveNav3 = "1.3.0-alpha09" +uiGraphicsVersion = "1.10.4" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -36,9 +36,9 @@ androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", vers androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } androidx-material3-adaptive-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "material3AdaptiveNav3" } +ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphicsVersion" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization"} - +jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"} From bf5060e28fc7d5f3e0de74ff6d9656214bcd6433 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 21 Mar 2026 14:14:04 -0400 Subject: [PATCH 2/7] Revert "Onboarding screen without login interface" This reverts commit 59156bed9d118b76aedfe77d45b61e087e51d15a. --- app/build.gradle.kts | 7 +- .../com/cornellappdev/chimes/MainActivity.kt | 3 +- .../chimes/ui/screens/Onboarding.kt | 243 ---------------- app/src/main/res/drawable/ic_clock.xml | 16 -- app/src/main/res/drawable/ic_hour_hand.xml | 12 - app/src/main/res/drawable/ic_logo.xml | 16 -- app/src/main/res/drawable/ic_minute_hand.xml | 12 - .../res/drawable/ic_onboarding_background.xml | 262 ------------------ gradle.properties | 5 +- gradle/libs.versions.toml | 6 +- 10 files changed, 9 insertions(+), 573 deletions(-) delete mode 100644 app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt delete mode 100644 app/src/main/res/drawable/ic_clock.xml delete mode 100644 app/src/main/res/drawable/ic_hour_hand.xml delete mode 100644 app/src/main/res/drawable/ic_logo.xml delete mode 100644 app/src/main/res/drawable/ic_minute_hand.xml delete mode 100644 app/src/main/res/drawable/ic_onboarding_background.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 86c9c8f..ac40860 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,12 +5,14 @@ plugins { android { namespace = "com.cornellappdev.chimes" - compileSdk = 35 + compileSdk { + version = release(36) + } defaultConfig { applicationId = "com.cornellappdev.chimes" minSdk = 24 - targetSdk = 35 + targetSdk = 36 versionCode = 1 versionName = "1.0" @@ -45,7 +47,6 @@ dependencies { implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.material3) implementation(libs.androidx.ui.graphics) - implementation(libs.ui.graphics) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) diff --git a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt index 3bd32f7..3588561 100644 --- a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt +++ b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt @@ -47,7 +47,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.cornellappdev.chimes.ui.components.HeaderButton import com.cornellappdev.chimes.ui.screens.HomeScreen -import com.cornellappdev.chimes.ui.screens.Onboarding import com.cornellappdev.chimes.ui.theme.ChimesandroidTheme class MainActivity : ComponentActivity() { @@ -56,7 +55,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { - Onboarding() + HomeScreen() } } } diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt deleted file mode 100644 index 4946fcf..0000000 --- a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt +++ /dev/null @@ -1,243 +0,0 @@ -package com.cornellappdev.chimes.ui.screens - -import android.annotation.SuppressLint -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.FastOutSlowInEasing -import androidx.compose.animation.core.LinearEasing -import androidx.compose.animation.core.tween -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.CompositingStrategy -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.cornellappdev.chimes.R -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch - - -@Composable -fun Onboarding () { - val bgAlpha = remember { Animatable(1f) } - val whiteAlpha = remember { Animatable(0f) } - val logoAlpha = remember { Animatable(0f) } - val logoScale = remember { Animatable(1f) } - val chimesAlpha = remember { Animatable(0f) } - val headerOffsetY = remember { Animatable(0f) } - val loginAlpha = remember { Animatable(0f) } - val minuteHandRotation = remember { Animatable(0f) } - val hourHandRotation = remember { Animatable(0f) } - var handsSpinStarted by remember { mutableStateOf(false) } - - LaunchedEffect(Unit) { - delay(300) - - launch { - bgAlpha.animateTo(0f, tween(300, easing = LinearEasing)) - } - - delay(300) - launch { - whiteAlpha.animateTo(1f, tween(300, easing = LinearEasing)) - } - delay(300) - logoAlpha.animateTo(1f, tween(300, easing = LinearEasing)) - - delay(300) - - logoScale.animateTo(0.55f, tween(300, easing = FastOutSlowInEasing)) - handsSpinStarted = true - - - delay(300) - chimesAlpha.animateTo(1f, tween(300, easing = LinearEasing)) - - delay(300) - launch { - headerOffsetY.animateTo(-90f, tween(300, easing = FastOutSlowInEasing)) - } - delay(300) - loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) - } - - LaunchedEffect(handsSpinStarted) { - if (!handsSpinStarted) return@LaunchedEffect - - launch { - while (isActive) { - minuteHandRotation.animateTo( - minuteHandRotation.value + 360f, - animationSpec = tween(durationMillis = 2_000, easing = LinearEasing) - ) - } - } - launch { - while (isActive) { - hourHandRotation.animateTo( - hourHandRotation.value + 360f, - animationSpec = tween(durationMillis = 10_000, easing = LinearEasing) - ) - } - } - } - - Box(modifier = Modifier.fillMaxSize().background(Color.White)) { - - Image( - painter = painterResource(id = R.drawable.ic_onboarding_background), - contentDescription = "Onboarding background", - modifier = Modifier - .fillMaxSize() - .alpha(bgAlpha.value), - contentScale = ContentScale.Crop - ) - - - - /* - //with gradient fade - Image( - painter = painterResource(id = R.drawable.ic_onboarding_background), - contentDescription = "Onboarding background", - modifier = Modifier - .fillMaxSize() - .graphicsLayer{ - compositingStrategy = CompositingStrategy.Offscreen - } - .drawWithContent{ - drawContent() - val brush = Brush.verticalGradient( - 0f to Color.White, - bgAlpha.value to Color.Transparent - ) - drawRect(brush = brush, blendMode = BlendMode.DstIn) - }, - contentScale = ContentScale.Crop - ) - - */ - - /* - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.White) - .alpha(whiteAlpha.value) - ) - - */ - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Spacer(modifier = Modifier.height(headerOffsetY.value.dp)) - - ClockLogo( - modifier = Modifier - .size((300 * logoScale.value).dp) - .alpha(logoAlpha.value), - minuteHandRotation = minuteHandRotation.value, - hourHandRotation = hourHandRotation.value - ) - - Spacer(modifier = Modifier.height(10.dp)) - - Text( - text = "chimes", - style = MaterialTheme.typography.titleMedium.copy( - fontWeight = FontWeight.Medium, - color = Color(0xFFE24B4B) - ), - modifier = Modifier.alpha(chimesAlpha.value), - fontSize = 18.sp - ) - Spacer(modifier = Modifier.height(140.dp)) - } - } -} - -@SuppressLint("UnusedBoxWithConstraintsScope") -@Composable -private fun ClockLogo( - modifier: Modifier = Modifier, - minuteHandRotation: Float, - hourHandRotation: Float -) { - BoxWithConstraints( - modifier = modifier, - contentAlignment = Alignment.Center - ) { - val clockSize = maxWidth * (69f / 118f) - // Adjust these coefficients to make the hands smaller/larger - val minuteHandWidth = maxWidth * 0.21f - val minuteHandHeight = maxWidth * 0.12f - val hourHandWidth = maxWidth * 0.17f - val hourHandHeight = maxWidth * 0.14f - - Image( - painter = painterResource(id = R.drawable.ic_clock), - contentDescription = "Clock base", - contentScale = ContentScale.FillBounds, - modifier = Modifier.size(clockSize) - ) - - Image( - painter = painterResource(id = R.drawable.ic_hour_hand), - contentDescription = "Hour hand", - contentScale = ContentScale.FillBounds, - modifier = Modifier - .size(hourHandWidth, hourHandHeight) - .graphicsLayer { - var value = 11f / 30f - translationX = (0.5f - value) * size.width - translationY = (0.5f - value) * size.height - - rotationZ = hourHandRotation - transformOrigin = TransformOrigin(value, value) - } - ) - - Image( - painter = painterResource(id = R.drawable.ic_minute_hand), - contentDescription = "Minute hand", - contentScale = ContentScale.FillBounds, - modifier = Modifier - .size(minuteHandWidth, minuteHandHeight) - .graphicsLayer { - var xValue = 2.5f/25f - var yValue = 16.5f/25f - - translationX = (0.5f - xValue) * size.width - translationY = (0.5f - yValue) * size.height - - rotationZ = minuteHandRotation - transformOrigin = TransformOrigin(xValue, yValue) - } - ) - } -} diff --git a/app/src/main/res/drawable/ic_clock.xml b/app/src/main/res/drawable/ic_clock.xml deleted file mode 100644 index 45922c7..0000000 --- a/app/src/main/res/drawable/ic_clock.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_hour_hand.xml b/app/src/main/res/drawable/ic_hour_hand.xml deleted file mode 100644 index 9546a8f..0000000 --- a/app/src/main/res/drawable/ic_hour_hand.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml deleted file mode 100644 index 36826da..0000000 --- a/app/src/main/res/drawable/ic_logo.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_minute_hand.xml b/app/src/main/res/drawable/ic_minute_hand.xml deleted file mode 100644 index e1f907d..0000000 --- a/app/src/main/res/drawable/ic_minute_hand.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_onboarding_background.xml b/app/src/main/res/drawable/ic_onboarding_background.xml deleted file mode 100644 index 1b65158..0000000 --- a/app/src/main/res/drawable/ic_onboarding_background.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gradle.properties b/gradle.properties index f533532..20e2a01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,4 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true - -# Disable file system watching to prevent file locking issues on Windows/OneDrive -org.gradle.vfs.watch=false \ No newline at end of file +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a667456..c675daf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,9 +11,9 @@ composeBom = "2024.09.00" uiGraphics = "1.10.2" nav3Core = "1.0.1" lifecycleViewmodelNav3 = "2.11.0-alpha01" +kotlinSerialization = "2.2.21" kotlinxSerializationCore = "1.9.0" material3AdaptiveNav3 = "1.3.0-alpha09" -uiGraphicsVersion = "1.10.4" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -36,9 +36,9 @@ androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", vers androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } androidx-material3-adaptive-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "material3AdaptiveNav3" } -ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphicsVersion" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"} +jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization"} + From 1d8ce2c0156be9221f74f2b0c6790069e2784c29 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 21 Mar 2026 14:18:27 -0400 Subject: [PATCH 3/7] Reapply "Onboarding screen without login interface" This reverts commit bf5060e28fc7d5f3e0de74ff6d9656214bcd6433. --- app/build.gradle.kts | 7 +- .../com/cornellappdev/chimes/MainActivity.kt | 3 +- .../chimes/ui/screens/Onboarding.kt | 243 ++++++++++++++++ app/src/main/res/drawable/ic_clock.xml | 16 ++ app/src/main/res/drawable/ic_hour_hand.xml | 12 + app/src/main/res/drawable/ic_logo.xml | 16 ++ app/src/main/res/drawable/ic_minute_hand.xml | 12 + .../res/drawable/ic_onboarding_background.xml | 262 ++++++++++++++++++ gradle.properties | 5 +- gradle/libs.versions.toml | 6 +- 10 files changed, 573 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt create mode 100644 app/src/main/res/drawable/ic_clock.xml create mode 100644 app/src/main/res/drawable/ic_hour_hand.xml create mode 100644 app/src/main/res/drawable/ic_logo.xml create mode 100644 app/src/main/res/drawable/ic_minute_hand.xml create mode 100644 app/src/main/res/drawable/ic_onboarding_background.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ac40860..86c9c8f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,14 +5,12 @@ plugins { android { namespace = "com.cornellappdev.chimes" - compileSdk { - version = release(36) - } + compileSdk = 35 defaultConfig { applicationId = "com.cornellappdev.chimes" minSdk = 24 - targetSdk = 36 + targetSdk = 35 versionCode = 1 versionName = "1.0" @@ -47,6 +45,7 @@ dependencies { implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.material3) implementation(libs.androidx.ui.graphics) + implementation(libs.ui.graphics) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) diff --git a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt index 3588561..3bd32f7 100644 --- a/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt +++ b/app/src/main/java/com/cornellappdev/chimes/MainActivity.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.cornellappdev.chimes.ui.components.HeaderButton import com.cornellappdev.chimes.ui.screens.HomeScreen +import com.cornellappdev.chimes.ui.screens.Onboarding import com.cornellappdev.chimes.ui.theme.ChimesandroidTheme class MainActivity : ComponentActivity() { @@ -55,7 +56,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { - HomeScreen() + Onboarding() } } } diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt new file mode 100644 index 0000000..4946fcf --- /dev/null +++ b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt @@ -0,0 +1,243 @@ +package com.cornellappdev.chimes.ui.screens + +import android.annotation.SuppressLint +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy +import androidx.compose.ui.graphics.TransformOrigin +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.cornellappdev.chimes.R +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + + +@Composable +fun Onboarding () { + val bgAlpha = remember { Animatable(1f) } + val whiteAlpha = remember { Animatable(0f) } + val logoAlpha = remember { Animatable(0f) } + val logoScale = remember { Animatable(1f) } + val chimesAlpha = remember { Animatable(0f) } + val headerOffsetY = remember { Animatable(0f) } + val loginAlpha = remember { Animatable(0f) } + val minuteHandRotation = remember { Animatable(0f) } + val hourHandRotation = remember { Animatable(0f) } + var handsSpinStarted by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { + delay(300) + + launch { + bgAlpha.animateTo(0f, tween(300, easing = LinearEasing)) + } + + delay(300) + launch { + whiteAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + } + delay(300) + logoAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + + delay(300) + + logoScale.animateTo(0.55f, tween(300, easing = FastOutSlowInEasing)) + handsSpinStarted = true + + + delay(300) + chimesAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + + delay(300) + launch { + headerOffsetY.animateTo(-90f, tween(300, easing = FastOutSlowInEasing)) + } + delay(300) + loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + } + + LaunchedEffect(handsSpinStarted) { + if (!handsSpinStarted) return@LaunchedEffect + + launch { + while (isActive) { + minuteHandRotation.animateTo( + minuteHandRotation.value + 360f, + animationSpec = tween(durationMillis = 2_000, easing = LinearEasing) + ) + } + } + launch { + while (isActive) { + hourHandRotation.animateTo( + hourHandRotation.value + 360f, + animationSpec = tween(durationMillis = 10_000, easing = LinearEasing) + ) + } + } + } + + Box(modifier = Modifier.fillMaxSize().background(Color.White)) { + + Image( + painter = painterResource(id = R.drawable.ic_onboarding_background), + contentDescription = "Onboarding background", + modifier = Modifier + .fillMaxSize() + .alpha(bgAlpha.value), + contentScale = ContentScale.Crop + ) + + + + /* + //with gradient fade + Image( + painter = painterResource(id = R.drawable.ic_onboarding_background), + contentDescription = "Onboarding background", + modifier = Modifier + .fillMaxSize() + .graphicsLayer{ + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent{ + drawContent() + val brush = Brush.verticalGradient( + 0f to Color.White, + bgAlpha.value to Color.Transparent + ) + drawRect(brush = brush, blendMode = BlendMode.DstIn) + }, + contentScale = ContentScale.Crop + ) + + */ + + /* + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) + .alpha(whiteAlpha.value) + ) + + */ + + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Spacer(modifier = Modifier.height(headerOffsetY.value.dp)) + + ClockLogo( + modifier = Modifier + .size((300 * logoScale.value).dp) + .alpha(logoAlpha.value), + minuteHandRotation = minuteHandRotation.value, + hourHandRotation = hourHandRotation.value + ) + + Spacer(modifier = Modifier.height(10.dp)) + + Text( + text = "chimes", + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Medium, + color = Color(0xFFE24B4B) + ), + modifier = Modifier.alpha(chimesAlpha.value), + fontSize = 18.sp + ) + Spacer(modifier = Modifier.height(140.dp)) + } + } +} + +@SuppressLint("UnusedBoxWithConstraintsScope") +@Composable +private fun ClockLogo( + modifier: Modifier = Modifier, + minuteHandRotation: Float, + hourHandRotation: Float +) { + BoxWithConstraints( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + val clockSize = maxWidth * (69f / 118f) + // Adjust these coefficients to make the hands smaller/larger + val minuteHandWidth = maxWidth * 0.21f + val minuteHandHeight = maxWidth * 0.12f + val hourHandWidth = maxWidth * 0.17f + val hourHandHeight = maxWidth * 0.14f + + Image( + painter = painterResource(id = R.drawable.ic_clock), + contentDescription = "Clock base", + contentScale = ContentScale.FillBounds, + modifier = Modifier.size(clockSize) + ) + + Image( + painter = painterResource(id = R.drawable.ic_hour_hand), + contentDescription = "Hour hand", + contentScale = ContentScale.FillBounds, + modifier = Modifier + .size(hourHandWidth, hourHandHeight) + .graphicsLayer { + var value = 11f / 30f + translationX = (0.5f - value) * size.width + translationY = (0.5f - value) * size.height + + rotationZ = hourHandRotation + transformOrigin = TransformOrigin(value, value) + } + ) + + Image( + painter = painterResource(id = R.drawable.ic_minute_hand), + contentDescription = "Minute hand", + contentScale = ContentScale.FillBounds, + modifier = Modifier + .size(minuteHandWidth, minuteHandHeight) + .graphicsLayer { + var xValue = 2.5f/25f + var yValue = 16.5f/25f + + translationX = (0.5f - xValue) * size.width + translationY = (0.5f - yValue) * size.height + + rotationZ = minuteHandRotation + transformOrigin = TransformOrigin(xValue, yValue) + } + ) + } +} diff --git a/app/src/main/res/drawable/ic_clock.xml b/app/src/main/res/drawable/ic_clock.xml new file mode 100644 index 0000000..45922c7 --- /dev/null +++ b/app/src/main/res/drawable/ic_clock.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_hour_hand.xml b/app/src/main/res/drawable/ic_hour_hand.xml new file mode 100644 index 0000000..9546a8f --- /dev/null +++ b/app/src/main/res/drawable/ic_hour_hand.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..36826da --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_minute_hand.xml b/app/src/main/res/drawable/ic_minute_hand.xml new file mode 100644 index 0000000..e1f907d --- /dev/null +++ b/app/src/main/res/drawable/ic_minute_hand.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_onboarding_background.xml b/app/src/main/res/drawable/ic_onboarding_background.xml new file mode 100644 index 0000000..1b65158 --- /dev/null +++ b/app/src/main/res/drawable/ic_onboarding_background.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle.properties b/gradle.properties index 20e2a01..f533532 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,7 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true + +# Disable file system watching to prevent file locking issues on Windows/OneDrive +org.gradle.vfs.watch=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c675daf..a667456 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,9 +11,9 @@ composeBom = "2024.09.00" uiGraphics = "1.10.2" nav3Core = "1.0.1" lifecycleViewmodelNav3 = "2.11.0-alpha01" -kotlinSerialization = "2.2.21" kotlinxSerializationCore = "1.9.0" material3AdaptiveNav3 = "1.3.0-alpha09" +uiGraphicsVersion = "1.10.4" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -36,9 +36,9 @@ androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", vers androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } androidx-material3-adaptive-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "material3AdaptiveNav3" } +ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphicsVersion" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization"} - +jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"} From d4e8da2cfbf85d7a1064acb5f60ce061d8ef9e20 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 26 Mar 2026 01:04:03 -0400 Subject: [PATCH 4/7] finished onboarding screen ui added login interface buttons and fixed all spacing requirements --- .../chimes/ui/screens/Onboarding.kt | 213 +++++++++++++----- app/src/main/res/drawable/ic_cornell_logo.xml | 168 ++++++++++++++ app/src/main/res/drawable/ic_google_g.xml | 18 ++ 3 files changed, 344 insertions(+), 55 deletions(-) create mode 100644 app/src/main/res/drawable/ic_cornell_logo.xml create mode 100644 app/src/main/res/drawable/ic_google_g.xml diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt index 4946fcf..58ec3ad 100644 --- a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt +++ b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt @@ -7,9 +7,12 @@ import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -29,6 +32,7 @@ import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.cornellappdev.chimes.R @@ -46,6 +50,7 @@ fun Onboarding () { val chimesAlpha = remember { Animatable(0f) } val headerOffsetY = remember { Animatable(0f) } val loginAlpha = remember { Animatable(0f) } + val loginOffsetY = remember { Animatable(300f) } // Starts 300dp below val minuteHandRotation = remember { Animatable(0f) } val hourHandRotation = remember { Animatable(0f) } var handsSpinStarted by remember { mutableStateOf(false) } @@ -75,10 +80,13 @@ fun Onboarding () { delay(300) launch { - headerOffsetY.animateTo(-90f, tween(300, easing = FastOutSlowInEasing)) + headerOffsetY.animateTo(-100f, tween(300, easing = FastOutSlowInEasing)) } delay(300) - loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) + launch { + loginOffsetY.animateTo(0f, tween(300, easing = FastOutSlowInEasing)) //slide + } + loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) //fade } LaunchedEffect(handsSpinStarted) { @@ -102,7 +110,7 @@ fun Onboarding () { } } - Box(modifier = Modifier.fillMaxSize().background(Color.White)) { + Box(modifier = Modifier.fillMaxSize().background(Color(0xFFFEF7F7))) { Image( painter = painterResource(id = R.drawable.ic_onboarding_background), @@ -113,53 +121,19 @@ fun Onboarding () { contentScale = ContentScale.Crop ) - - - /* - //with gradient fade - Image( - painter = painterResource(id = R.drawable.ic_onboarding_background), - contentDescription = "Onboarding background", - modifier = Modifier - .fillMaxSize() - .graphicsLayer{ - compositingStrategy = CompositingStrategy.Offscreen - } - .drawWithContent{ - drawContent() - val brush = Brush.verticalGradient( - 0f to Color.White, - bgAlpha.value to Color.Transparent - ) - drawRect(brush = brush, blendMode = BlendMode.DstIn) - }, - contentScale = ContentScale.Crop - ) - - */ - - /* - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.White) - .alpha(whiteAlpha.value) - ) - - */ - Column( modifier = Modifier .fillMaxSize() - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + .padding(horizontal = 24.dp) + .offset(y = headerOffsetY.value.dp), + horizontalAlignment = Alignment.CenterHorizontally ) { - Spacer(modifier = Modifier.height(headerOffsetY.value.dp)) + + Spacer(modifier = Modifier.weight(1f)) //top half of screen ClockLogo( modifier = Modifier - .size((300 * logoScale.value).dp) + .size((150 * logoScale.value).dp) .alpha(logoAlpha.value), minuteHandRotation = minuteHandRotation.value, hourHandRotation = hourHandRotation.value @@ -171,12 +145,140 @@ fun Onboarding () { text = "chimes", style = MaterialTheme.typography.titleMedium.copy( fontWeight = FontWeight.Medium, - color = Color(0xFFE24B4B) + color = Color(0xFFCC5555) ), modifier = Modifier.alpha(chimesAlpha.value), - fontSize = 18.sp + fontSize = 40.sp ) - Spacer(modifier = Modifier.height(140.dp)) + + // this box takes up the bottom half of the screen, so the login buttons won't push the logo up + Box( + modifier = Modifier.weight(1f), + contentAlignment = Alignment.TopCenter + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .alpha(loginAlpha.value) + .offset(y = loginOffsetY.value.dp) + .width(333.dp) + ) { + val curve = 50.dp + + Spacer(modifier = Modifier.height(64.dp)) + + Button( + modifier = Modifier + .height(54.dp) + .border( + width = 1.dp, + color = Color(0XFFBCB2B2), + shape = RoundedCornerShape(curve) + ) + .fillMaxWidth(), + onClick = {}, + shape = RoundedCornerShape(curve), + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = Color.Black + ), + contentPadding = PaddingValues(horizontal = 20.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Image( + painter = painterResource(id = R.drawable.ic_google_g), + contentDescription = "Google logo", + modifier = Modifier.size(32.dp), + contentScale = ContentScale.Fit + ) + Spacer(modifier = Modifier.width(16.dp)) + Text( + text = "Log-in with Google", + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Normal, + color = Color.Black + ), + fontSize = 14.sp + ) + } + } + + Spacer(modifier = Modifier.height(15.dp)) + + Button( + modifier = Modifier + .height(54.dp) + .border( + width = 1.dp, + color = Color(0XFFBCB2B2), + shape = RoundedCornerShape(curve) + ) + .fillMaxWidth(), + onClick = {}, + shape = RoundedCornerShape(curve), + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = Color.Black + ), + contentPadding = PaddingValues(horizontal = 20.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Image( + painter = painterResource(id = R.drawable.ic_cornell_logo), + contentDescription = "Cornell logo", + modifier = Modifier.size(32.dp), + contentScale = ContentScale.Fit + ) + Spacer(modifier = Modifier.width(16.dp)) + Text( + text = "Log-in with Cornell netID", + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Normal, + color = Color.Black + ), + fontSize = 14.sp + ) + } + } + + Spacer(modifier = Modifier.height(45.dp)) + + HorizontalDivider( + color = Color(0XFFBCB2B2), + thickness = 1.dp, + modifier = Modifier + .width(200.dp) + ) + + Spacer(modifier = Modifier.height(45.dp)) + + Button( + onClick = {}, + colors = ButtonDefaults.buttonColors( + containerColor = Color.Transparent, + ), + shape = RoundedCornerShape(0.dp), + modifier = Modifier.height(25.dp), + contentPadding = PaddingValues(0.dp) + ) { + Text( + text = "log in without an account", + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Thin, + color = Color.Black, + textDecoration = TextDecoration.Underline + ), + fontSize = 8.sp + ) + } + } + } } } } @@ -192,12 +294,12 @@ private fun ClockLogo( modifier = modifier, contentAlignment = Alignment.Center ) { - val clockSize = maxWidth * (69f / 118f) - // Adjust these coefficients to make the hands smaller/larger - val minuteHandWidth = maxWidth * 0.21f - val minuteHandHeight = maxWidth * 0.12f - val hourHandWidth = maxWidth * 0.17f - val hourHandHeight = maxWidth * 0.14f + val clockSize = maxWidth + + val minuteHandWidth = maxWidth * 0.36f + val minuteHandHeight = maxWidth * 0.21f + val hourHandWidth = maxWidth * 0.29f + val hourHandHeight = maxWidth * 0.24f Image( painter = painterResource(id = R.drawable.ic_clock), @@ -213,7 +315,8 @@ private fun ClockLogo( modifier = Modifier .size(hourHandWidth, hourHandHeight) .graphicsLayer { - var value = 11f / 30f + val value = 11f / 30f + translationX = (0.5f - value) * size.width translationY = (0.5f - value) * size.height @@ -229,8 +332,8 @@ private fun ClockLogo( modifier = Modifier .size(minuteHandWidth, minuteHandHeight) .graphicsLayer { - var xValue = 2.5f/25f - var yValue = 16.5f/25f + val xValue = 2.5f/25f + val yValue = 16.5f/25f translationX = (0.5f - xValue) * size.width translationY = (0.5f - yValue) * size.height diff --git a/app/src/main/res/drawable/ic_cornell_logo.xml b/app/src/main/res/drawable/ic_cornell_logo.xml new file mode 100644 index 0000000..f93cc0c --- /dev/null +++ b/app/src/main/res/drawable/ic_cornell_logo.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_google_g.xml b/app/src/main/res/drawable/ic_google_g.xml new file mode 100644 index 0000000..021b162 --- /dev/null +++ b/app/src/main/res/drawable/ic_google_g.xml @@ -0,0 +1,18 @@ + + + + + + From 1d1978c4b1e71e5748747b705a3e31f3055f2fc8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Mar 2026 02:27:13 -0400 Subject: [PATCH 5/7] Addressed PR comments --- app/build.gradle.kts | 8 +- .../chimes/ui/screens/Onboarding.kt | 268 +++++++++--------- gradle/libs.versions.toml | 2 - 3 files changed, 132 insertions(+), 146 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 86c9c8f..d2ed35f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,12 +5,14 @@ plugins { android { namespace = "com.cornellappdev.chimes" - compileSdk = 35 + compileSdk { + version = release(36) + } defaultConfig { applicationId = "com.cornellappdev.chimes" minSdk = 24 - targetSdk = 35 + targetSdk = 36 versionCode = 1 versionName = "1.0" @@ -44,8 +46,6 @@ dependencies { implementation(libs.androidx.compose.ui.graphics) implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.material3) - implementation(libs.androidx.ui.graphics) - implementation(libs.ui.graphics) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt index 58ec3ad..d76637d 100644 --- a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt +++ b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt @@ -4,6 +4,10 @@ import android.annotation.SuppressLint import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -13,7 +17,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.MaterialTheme @@ -21,25 +25,23 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.CompositingStrategy import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.cornellappdev.chimes.R import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +private val ChimesRed = Color(0xFFCC5555) +private val VeryLightPink = Color(0xFFFEF7F7) +private val VeryLightGray = Color(0xFFBCB2B2) @Composable fun Onboarding () { @@ -51,22 +53,41 @@ fun Onboarding () { val headerOffsetY = remember { Animatable(0f) } val loginAlpha = remember { Animatable(0f) } val loginOffsetY = remember { Animatable(300f) } // Starts 300dp below - val minuteHandRotation = remember { Animatable(0f) } - val hourHandRotation = remember { Animatable(0f) } var handsSpinStarted by remember { mutableStateOf(false) } + val minuteHandRotation: Float + val hourHandRotation: Float + if (handsSpinStarted) { + val handsRotationTransition = rememberInfiniteTransition(label = "handsRotationTransition") + val minuteRotation by handsRotationTransition.animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(durationMillis = 2_000, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ), + label = "minuteHandRotation" + ) + val hourRotation by handsRotationTransition.animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(durationMillis = 10_000, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ), + label = "hourHandRotation" + ) + minuteHandRotation = minuteRotation + hourHandRotation = hourRotation + } else { + minuteHandRotation = 0f + hourHandRotation = 0f + } LaunchedEffect(Unit) { delay(300) - launch { - bgAlpha.animateTo(0f, tween(300, easing = LinearEasing)) - } - - delay(300) - launch { - whiteAlpha.animateTo(1f, tween(300, easing = LinearEasing)) - } - delay(300) + bgAlpha.animateTo(0f, tween(300, easing = LinearEasing)) + whiteAlpha.animateTo(1f, tween(300, easing = LinearEasing)) logoAlpha.animateTo(1f, tween(300, easing = LinearEasing)) delay(300) @@ -74,43 +95,22 @@ fun Onboarding () { logoScale.animateTo(0.55f, tween(300, easing = FastOutSlowInEasing)) handsSpinStarted = true - delay(300) chimesAlpha.animateTo(1f, tween(300, easing = LinearEasing)) delay(300) - launch { - headerOffsetY.animateTo(-100f, tween(300, easing = FastOutSlowInEasing)) - } + + headerOffsetY.animateTo(-100f, tween(300, easing = FastOutSlowInEasing)) + delay(300) + launch { loginOffsetY.animateTo(0f, tween(300, easing = FastOutSlowInEasing)) //slide } loginAlpha.animateTo(1f, tween(300, easing = LinearEasing)) //fade } - LaunchedEffect(handsSpinStarted) { - if (!handsSpinStarted) return@LaunchedEffect - - launch { - while (isActive) { - minuteHandRotation.animateTo( - minuteHandRotation.value + 360f, - animationSpec = tween(durationMillis = 2_000, easing = LinearEasing) - ) - } - } - launch { - while (isActive) { - hourHandRotation.animateTo( - hourHandRotation.value + 360f, - animationSpec = tween(durationMillis = 10_000, easing = LinearEasing) - ) - } - } - } - - Box(modifier = Modifier.fillMaxSize().background(Color(0xFFFEF7F7))) { + Box(modifier = Modifier.fillMaxSize().background(VeryLightPink)) { Image( painter = painterResource(id = R.drawable.ic_onboarding_background), @@ -135,8 +135,8 @@ fun Onboarding () { modifier = Modifier .size((150 * logoScale.value).dp) .alpha(logoAlpha.value), - minuteHandRotation = minuteHandRotation.value, - hourHandRotation = hourHandRotation.value + minuteHandRotation = minuteHandRotation, + hourHandRotation = hourHandRotation ) Spacer(modifier = Modifier.height(10.dp)) @@ -145,7 +145,7 @@ fun Onboarding () { text = "chimes", style = MaterialTheme.typography.titleMedium.copy( fontWeight = FontWeight.Medium, - color = Color(0xFFCC5555) + color = ChimesRed ), modifier = Modifier.alpha(chimesAlpha.value), fontSize = 40.sp @@ -161,96 +161,31 @@ fun Onboarding () { modifier = Modifier .alpha(loginAlpha.value) .offset(y = loginOffsetY.value.dp) - .width(333.dp) + .fillMaxWidth() + .padding(horizontal = 15.dp) ) { - val curve = 50.dp - Spacer(modifier = Modifier.height(64.dp)) - Button( - modifier = Modifier - .height(54.dp) - .border( - width = 1.dp, - color = Color(0XFFBCB2B2), - shape = RoundedCornerShape(curve) - ) - .fillMaxWidth(), - onClick = {}, - shape = RoundedCornerShape(curve), - colors = ButtonDefaults.buttonColors( - containerColor = Color.White, - contentColor = Color.Black - ), - contentPadding = PaddingValues(horizontal = 20.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Image( - painter = painterResource(id = R.drawable.ic_google_g), - contentDescription = "Google logo", - modifier = Modifier.size(32.dp), - contentScale = ContentScale.Fit - ) - Spacer(modifier = Modifier.width(16.dp)) - Text( - text = "Log-in with Google", - style = MaterialTheme.typography.titleMedium.copy( - fontWeight = FontWeight.Normal, - color = Color.Black - ), - fontSize = 14.sp - ) - } - } + LoginButton( + text = "Log-in with Google", + iconRes = R.drawable.ic_google_g, + contentDescription = "Google logo", + onClick = {} + ) Spacer(modifier = Modifier.height(15.dp)) - Button( - modifier = Modifier - .height(54.dp) - .border( - width = 1.dp, - color = Color(0XFFBCB2B2), - shape = RoundedCornerShape(curve) - ) - .fillMaxWidth(), - onClick = {}, - shape = RoundedCornerShape(curve), - colors = ButtonDefaults.buttonColors( - containerColor = Color.White, - contentColor = Color.Black - ), - contentPadding = PaddingValues(horizontal = 20.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Image( - painter = painterResource(id = R.drawable.ic_cornell_logo), - contentDescription = "Cornell logo", - modifier = Modifier.size(32.dp), - contentScale = ContentScale.Fit - ) - Spacer(modifier = Modifier.width(16.dp)) - Text( - text = "Log-in with Cornell netID", - style = MaterialTheme.typography.titleMedium.copy( - fontWeight = FontWeight.Normal, - color = Color.Black - ), - fontSize = 14.sp - ) - } - } + LoginButton( + text = "Log-in with Cornell netID", + iconRes = R.drawable.ic_cornell_logo, + contentDescription = "Cornell logo", + onClick = {} + ) Spacer(modifier = Modifier.height(45.dp)) HorizontalDivider( - color = Color(0XFFBCB2B2), + color = VeryLightGray, thickness = 1.dp, modifier = Modifier .width(200.dp) @@ -258,11 +193,9 @@ fun Onboarding () { Spacer(modifier = Modifier.height(45.dp)) - Button( + + TextButton( onClick = {}, - colors = ButtonDefaults.buttonColors( - containerColor = Color.Transparent, - ), shape = RoundedCornerShape(0.dp), modifier = Modifier.height(25.dp), contentPadding = PaddingValues(0.dp) @@ -283,6 +216,55 @@ fun Onboarding () { } } +@Composable +private fun LoginButton( + text: String, + iconRes: Int, + contentDescription: String, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + val curve = 50.dp + Button( + modifier = modifier + .height(54.dp) + .border( + width = 1.dp, + color = VeryLightGray, + shape = RoundedCornerShape(curve) + ) + .fillMaxWidth(), + onClick = onClick, + shape = RoundedCornerShape(curve), + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = Color.Black + ), + contentPadding = PaddingValues(horizontal = 20.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Icon( + painter = painterResource(id = iconRes), + contentDescription = contentDescription, + modifier = Modifier.size(32.dp), + tint = Color.Unspecified + ) + Spacer(modifier = Modifier.width(16.dp)) + Text( + text = text, + style = MaterialTheme.typography.titleMedium.copy( + fontWeight = FontWeight.Normal, + color = Color.Black + ), + fontSize = 14.sp + ) + } + } +} + @SuppressLint("UnusedBoxWithConstraintsScope") @Composable private fun ClockLogo( @@ -315,13 +297,13 @@ private fun ClockLogo( modifier = Modifier .size(hourHandWidth, hourHandHeight) .graphicsLayer { - val value = 11f / 30f + val pivotFraction = 11f / 30f - translationX = (0.5f - value) * size.width - translationY = (0.5f - value) * size.height + translationX = (0.5f - pivotFraction) * size.width + translationY = (0.5f - pivotFraction) * size.height rotationZ = hourHandRotation - transformOrigin = TransformOrigin(value, value) + transformOrigin = TransformOrigin(pivotFraction, pivotFraction) } ) @@ -332,15 +314,21 @@ private fun ClockLogo( modifier = Modifier .size(minuteHandWidth, minuteHandHeight) .graphicsLayer { - val xValue = 2.5f/25f - val yValue = 16.5f/25f + val pivotFractionX = 2.5f/25f + val pivotFractionY = 16.5f/25f - translationX = (0.5f - xValue) * size.width - translationY = (0.5f - yValue) * size.height + translationX = (0.5f - pivotFractionX) * size.width + translationY = (0.5f - pivotFractionY) * size.height rotationZ = minuteHandRotation - transformOrigin = TransformOrigin(xValue, yValue) + transformOrigin = TransformOrigin(pivotFractionX, pivotFractionY) } ) } } + +@Preview +@Composable +fun OnboardingPreview() { + Onboarding() +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a667456..0600b4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,6 @@ nav3Core = "1.0.1" lifecycleViewmodelNav3 = "2.11.0-alpha01" kotlinxSerializationCore = "1.9.0" material3AdaptiveNav3 = "1.3.0-alpha09" -uiGraphicsVersion = "1.10.4" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -36,7 +35,6 @@ androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", vers androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycleViewmodelNav3" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" } androidx-material3-adaptive-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "material3AdaptiveNav3" } -ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphicsVersion" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 75f56d72509e4af25c7d4d1b7289518f96542e34 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Mar 2026 14:20:12 -0400 Subject: [PATCH 6/7] Cleanup --- gradle.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index f533532..132244e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,6 +21,3 @@ kotlin.code.style=official # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true - -# Disable file system watching to prevent file locking issues on Windows/OneDrive -org.gradle.vfs.watch=false \ No newline at end of file From 7a24d511664066d414def3c1c871a51250bfbf76 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Mar 2026 14:47:15 -0400 Subject: [PATCH 7/7] Addressed onLoginClick mutable state comments --- .../chimes/ui/navigation/MainNavigation.kt | 2 +- .../cornellappdev/chimes/ui/screens/Onboarding.kt | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/navigation/MainNavigation.kt b/app/src/main/java/com/cornellappdev/chimes/ui/navigation/MainNavigation.kt index 95e6676..9476a52 100644 --- a/app/src/main/java/com/cornellappdev/chimes/ui/navigation/MainNavigation.kt +++ b/app/src/main/java/com/cornellappdev/chimes/ui/navigation/MainNavigation.kt @@ -23,7 +23,7 @@ fun MainNavigation() { entryProvider = entryProvider { entry { Onboarding( - onLoginButtonClick = { + onLoginClick = { backStack.clear() backStack.add(NavigationItem.Home) } diff --git a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt index 06b4e94..673fe43 100644 --- a/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt +++ b/app/src/main/java/com/cornellappdev/chimes/ui/screens/Onboarding.kt @@ -42,13 +42,11 @@ import kotlinx.coroutines.launch private val ChimesRed = Color(0xFFCC5555) private val VeryLightPink = Color(0xFFFEF7F7) private val VeryLightGray = Color(0xFFBCB2B2) -private var onLoginClick: () -> Unit = {} @Composable fun Onboarding( - onLoginButtonClick: () -> Unit = {} + onLoginClick: () -> Unit = {} ) { - onLoginClick = onLoginButtonClick val bgAlpha = remember { Animatable(1f) } val whiteAlpha = remember { Animatable(0f) } val logoAlpha = remember { Animatable(0f) } @@ -173,7 +171,8 @@ fun Onboarding( LoginButton( text = "Log-in with Google", iconRes = R.drawable.ic_google_g, - contentDescription = "Google logo" + contentDescription = "Google logo", + onClick = onLoginClick ) Spacer(modifier = Modifier.height(15.dp)) @@ -181,7 +180,8 @@ fun Onboarding( LoginButton( text = "Log-in with Cornell netID", iconRes = R.drawable.ic_cornell_logo, - contentDescription = "Cornell logo" + contentDescription = "Cornell logo", + onClick = onLoginClick ) Spacer(modifier = Modifier.height(45.dp)) @@ -222,6 +222,7 @@ fun Onboarding( private fun LoginButton( text: String, iconRes: Int, + onClick: () -> Unit, contentDescription: String, modifier: Modifier = Modifier ) { @@ -235,7 +236,7 @@ private fun LoginButton( shape = RoundedCornerShape(curve) ) .fillMaxWidth(), - onClick = onLoginClick, + onClick = onClick, shape = RoundedCornerShape(curve), colors = ButtonDefaults.buttonColors( containerColor = Color.White,