From 7fe7ddb16087a559fdf80bfdfee97c46e3100bd1 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 16:07:56 +0530 Subject: [PATCH 1/6] Added changes to the Signin screen as per the ui feedback --- .../sample/ui/components/FactorCard.kt | 52 +++++-- .../sample/ui/screens/ChooseSignInScreen.kt | 144 +++++++++++++----- .../auth0/android/sample/ui/theme/Color.kt | 64 +++++++- 3 files changed, 204 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt index ffa527f..b9e0902 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt @@ -2,7 +2,8 @@ package com.auth0.android.sample.ui.components import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -18,7 +19,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.dp import com.auth0.universalcomponents.theme.Auth0Theme @@ -31,6 +31,7 @@ import com.auth0.universalcomponents.theme.Auth0Theme * @param title Factor name (e.g. "Hosted Login") * @param description Short description of the factor * @param icon Leading icon for the factor + * @param isSelected Whether this card is currently selected; shows bold border and filled radio indicator * @param onClick Callback when the card is tapped */ @Composable @@ -38,6 +39,7 @@ fun FactorCard( title: String, description: String, icon: Painter, + isSelected: Boolean = false, onClick: () -> Unit = {} ) { val colors = Auth0Theme.colors @@ -47,21 +49,22 @@ fun FactorCard( val sizes = Auth0Theme.sizes Card( - modifier = Modifier - .fillMaxWidth() - .height(112.dp) - .clickable { onClick() }, + onClick = onClick, + modifier = Modifier.fillMaxWidth(), shape = shapes.large, colors = CardDefaults.cardColors( - containerColor = Auth0Theme.colors.backgroundLayerBase + containerColor = if (isSelected) colors.backgroundLayerTop else colors.backgroundLayerMedium ), - border = BorderStroke(1.dp, colors.borderBold) + border = BorderStroke( + width = if (isSelected) 2.dp else 1.dp, + color = if (isSelected) colors.borderBold else colors.borderDefault + ) ) { Row( modifier = Modifier .fillMaxWidth() .padding(dimensions.spacingMd), - verticalAlignment = Alignment.Top + verticalAlignment = Alignment.CenterVertically ) { Icon( painter = icon, @@ -78,12 +81,41 @@ fun FactorCard( style = typography.title, color = colors.textBold ) + Spacer(modifier = Modifier.height(dimensions.spacingXxs)) Text( text = description, style = typography.body, - color = colors.textDefault + color = colors.textDefault, + minLines = 2 ) } + + Spacer(modifier = Modifier.width(dimensions.spacingMd)) + + // Radio selection indicator: filled dark circle + white dot when selected, + // empty light circle with grey ring when unselected. + Box( + modifier = Modifier + .size(20.dp) + .border( + width = if (isSelected) 0.dp else 1.dp, + color = if (isSelected) colors.backgroundPrimary else colors.borderDefault, + shape = shapes.full + ) + .background( + color = if (isSelected) colors.backgroundPrimary else colors.backgroundLayerBase, + shape = shapes.full + ), + contentAlignment = Alignment.Center + ) { + if (isSelected) { + Box( + modifier = Modifier + .size(8.dp) + .background(color = colors.backgroundLayerTop, shape = shapes.full) + ) + } + } } } } diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt index bca7c41..136114b 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt @@ -1,21 +1,28 @@ package com.auth0.android.sample.ui.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource @@ -23,79 +30,138 @@ import androidx.compose.ui.text.style.TextAlign import com.auth0.android.sample.ui.components.Auth0LogoHeader import com.auth0.android.sample.ui.components.FactorCard import com.auth0.android.sample.ui.theme.BackGroundColor +import com.auth0.android.sample.ui.theme.BottomCoolOverlay +import com.auth0.android.sample.ui.theme.BottomWarmOverlay +import com.auth0.android.sample.ui.theme.DarkBackGroundColor import com.auth0.universalcomponents.theme.Auth0Theme +private enum class LoginOption { Embedded, Hosted } + /** * Pre-login screen for choosing the sign-in method. * + * Cards are selectable — tapping a card sets the selection state. The Continue button + * navigates to the chosen flow and is disabled until a card is selected. + * * @param onEmbeddedLogin Navigate to embedded login * @param onHostedLogin Navigate to hosted (redirect) Auth0 login * @param onSettings Navigate to settings/appearance */ @Composable fun ChooseSignInScreen( - onEmbeddedLogin: () -> Unit, onHostedLogin: () -> Unit, onSettings: () -> Unit = {} + onEmbeddedLogin: () -> Unit, + onHostedLogin: () -> Unit, + onSettings: () -> Unit = {} ) { + var selectedOption by remember { mutableStateOf(null) } + val backgroundBrush = if (isSystemInDarkTheme()) DarkBackGroundColor else BackGroundColor + val isDark = isSystemInDarkTheme() val colors = Auth0Theme.colors val typography = Auth0Theme.typography val dimensions = Auth0Theme.dimensions + val shapes = Auth0Theme.shapes + val sizes = Auth0Theme.sizes + Column( modifier = Modifier .fillMaxSize() - .background(BackGroundColor) + .background(backgroundBrush) + .run { + // Layer warm (bottom-left) and cool/lavender (bottom-right) overlays + // to match the Figma diagonal gradient at the bottom of the screen. + if (!isDark) background(BottomWarmOverlay).background(BottomCoolOverlay) + else this + } .windowInsetsPadding(WindowInsets.navigationBars) - .verticalScroll(rememberScrollState()) - .padding(horizontal = dimensions.spacingLg), - horizontalAlignment = Alignment.CenterHorizontally ) { - Auth0LogoHeader() + // Scrollable main content — weight(1f) leaves room for the pinned Appearance button + Column( + modifier = Modifier + .weight(1f) + .verticalScroll(rememberScrollState()) + .padding(horizontal = dimensions.spacingLg), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.height(dimensions.spacingSm)) + + Auth0LogoHeader() + + Spacer(modifier = Modifier.height(dimensions.spacingXxl * 4)) - Spacer(modifier = Modifier.height(dimensions.spacingXxl * 4)) + Text( + text = "Choose how to sign in", + style = typography.display, + color = colors.textBold, + textAlign = TextAlign.Center + ) - Text( - text = "Choose how to sign in", - style = typography.display, - color = colors.textBold, - textAlign = TextAlign.Center - ) + Spacer(modifier = Modifier.height(dimensions.spacingLg)) - Spacer(modifier = Modifier.height(dimensions.spacingLg)) + FactorCard( + title = "Embedded Login", + description = "Total brand control and low user frictions", + icon = painterResource(com.auth0.android.sample.R.drawable.ic_embedded_login), + isSelected = selectedOption == LoginOption.Embedded, + onClick = { selectedOption = LoginOption.Embedded } + ) - FactorCard( - title = "Embedded Login", - description = "Total brand control and low user frictions", - icon = painterResource(com.auth0.android.sample.R.drawable.ic_embedded_login), - onClick = onEmbeddedLogin, - ) + Spacer(modifier = Modifier.height(dimensions.spacingMd)) - Spacer(modifier = Modifier.height(dimensions.spacingSm)) + FactorCard( + title = "Hosted Login", + description = "Easy to setup, works instantly", + icon = painterResource(com.auth0.android.sample.R.drawable.ic_hosted_login), + isSelected = selectedOption == LoginOption.Hosted, + onClick = { selectedOption = LoginOption.Hosted } + ) - FactorCard( - title = "Hosted Login", - description = "Easy to setup, works instantly", - icon = painterResource(com.auth0.android.sample.R.drawable.ic_hosted_login), - onClick = onHostedLogin, - ) + Spacer(modifier = Modifier.height(dimensions.spacingLg)) - Spacer(modifier = Modifier.height(dimensions.spacingXxl)) + Button( + onClick = { + when (selectedOption) { + LoginOption.Embedded -> onEmbeddedLogin() + LoginOption.Hosted -> onHostedLogin() + null -> Unit + } + }, + enabled = selectedOption != null, + modifier = Modifier + .fillMaxWidth() + .height(sizes.buttonHeight), + shape = shapes.large, + colors = ButtonDefaults.buttonColors( + containerColor = colors.backgroundPrimary, + contentColor = colors.textOnPrimary + ) + ) { + Text( + text = "Continue", + style = typography.label + ) + } - Row( + Spacer(modifier = Modifier.height(dimensions.spacingLg)) + } + + // Appearance — pinned at screen bottom, outside the scroll area + TextButton( + onClick = onSettings, modifier = Modifier - .padding(dimensions.spacingXs) - .clickable(onClick = onSettings), - verticalAlignment = Alignment.CenterVertically + .fillMaxWidth() + .padding(horizontal = dimensions.spacingLg, vertical = dimensions.spacingMd) ) { Icon( painter = painterResource(com.auth0.android.sample.R.drawable.ic_appearance_prefix), - contentDescription = "Appearance", - tint = Auth0Theme.colors.backgroundPrimary, + contentDescription = null, + tint = colors.textBold, modifier = Modifier.padding(end = dimensions.spacingXs) ) Text( - text = "Appearance", style = Auth0Theme.typography.title, color = Auth0Theme.colors.textBold + text = "Appearance", + style = typography.label, + color = colors.textBold ) } - - Spacer(modifier = Modifier.height(dimensions.spacingXl)) } } diff --git a/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt b/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt index c19e8b1..ed84dbf 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt @@ -12,14 +12,64 @@ val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) - +/** + * Light theme background — vertical base gradient. + * + * Sampled directly from the Figma design: + * #F4F4F5 — top of screen through end of cards (exact sample) + * #EDEBF1 — just below the cards (slight lavender tint, exact sample) + * #EBE1E4 — bottom centre (average of bottom-left #E9D7D4 warm and bottom-right #EDEBF4 lavender) + * + * Note: the bottom-left (#E9D7D4, warm) vs bottom-right (#EDEBF4, lavender) split + * is captured by a separate diagonal overlay brush — see [BottomWarmOverlay] and + * [BottomCoolOverlay] used in ChooseSignInScreen. + */ val BackGroundColor = Brush.linearGradient( - colors = listOf( - Color(0xFFF4F4F5), - Color(0xFFFCFCFC), - Color(0xFFECE5EB), - Color(0xFFEDE9F1) + colorStops = arrayOf( + 0.00f to Color(0xFFF4F4F5), + 0.75f to Color(0xFFEDEBF1), + 1.00f to Color(0xFFEBE1E4) + ), + start = Offset(0f, 0f), + end = Offset(0f, Float.POSITIVE_INFINITY) +) + +/** + * Warm (pinkish) overlay concentrated at the bottom-left corner. + * Blended on top of [BackGroundColor] to reproduce the #E9D7D4 bottom-left sample. + */ +val BottomWarmOverlay = Brush.radialGradient( + colors = listOf(Color(0x99E9D7D4), Color(0x00E9D7D4)), + center = Offset(0f, Float.POSITIVE_INFINITY), + radius = 900f +) + +/** + * Cool (lavender) overlay concentrated at the bottom-right corner. + * Blended on top of [BackGroundColor] to reproduce the #EDEBF4 bottom-right sample. + */ +val BottomCoolOverlay = Brush.radialGradient( + colors = listOf(Color(0x99EDEBF4), Color(0x00EDEBF4)), + center = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY), + radius = 900f +) + +/** + * Dark theme background gradient. + * + * Mirrors the light gradient: flat near-black base (#09090B) for the top 75%, + * then a warm amber/cream equivalent fades in at the bottom 25%. + * + * 0% #09090B — Auth0 backgroundLayerBase dark (near-black) + * 75% #0E0C09 — barely warm, still reads near-black + * 100% #221608 — dark warm amber at very bottom + */ +val DarkBackGroundColor = Brush.linearGradient( + colorStops = arrayOf( + 0.00f to Color(0xFF09090B), + 0.75f to Color(0xFF0E0C09), + 1.00f to Color(0xFF221608) ), start = Offset(0f, 0f), end = Offset(0f, Float.POSITIVE_INFINITY) -) \ No newline at end of file +) From 926a43c0e2f4237d3f4e040745a7c605f9e58418 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 17:20:05 +0530 Subject: [PATCH 2/6] Updated the dark theme design for the sample app --- .../sample/ui/components/Auth0LogoHeader.kt | 7 ++- .../sample/ui/components/FactorCard.kt | 44 ++++++++++++++----- .../sample/ui/screens/ChooseSignInScreen.kt | 18 ++------ .../sample/ui/screens/DashboardScreen.kt | 5 ++- .../sample/ui/screens/EmbeddedLoginScreen.kt | 4 +- .../sample/ui/screens/ExploreLoginScreen.kt | 4 +- .../sample/ui/theme/BackgroundModifier.kt | 29 ++++++++++++ .../auth0/android/sample/ui/theme/Color.kt | 26 +---------- 8 files changed, 80 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt b/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt index fecb5ca..ad5b302 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt @@ -24,6 +24,11 @@ fun Auth0LogoHeader( modifier: Modifier = Modifier, ) { val dimensions = Auth0Theme.dimensions + val colors = Auth0Theme.colors + // ic_auth0.xml paths are hardcoded #09090B — invisible on dark backgrounds. + // Detect dark mode from Auth0Theme tokens (not isSystemInDarkTheme) so the in-app + // theme switcher is respected. Light: preserve SVG fill. Dark: tint white (#FAFAFA). + val logoTint = if (colors.backgroundLayerBase.red < 0.1f) colors.textBold else Color.Unspecified Spacer(modifier = Modifier.height(dimensions.spacingXl)) @@ -35,7 +40,7 @@ fun Auth0LogoHeader( ) { Icon( painterResource(R.drawable.ic_auth0), contentDescription = "Auth0 logo", - tint = Color.Unspecified + tint = logoTint ) } } diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt index b9e0902..439cb87 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt @@ -47,17 +47,30 @@ fun FactorCard( val shapes = Auth0Theme.shapes val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes + // Detect current theme from Auth0Theme tokens (not isSystemInDarkTheme) so it + // respects the app's in-app theme switcher, not just the OS dark mode setting. + // backgroundLayerBase is #09090B (dark) vs #F4F4F5 (light) — red channel distinguishes them. + val isDark = colors.backgroundLayerBase.red < 0.1f + + // Light: selected=white (layerTop), unselected=near-white (layerMedium) + // Dark: both cards use layerMedium (#27272A); selection is shown via border only + val cardBackground = when { + isSelected && !isDark -> colors.backgroundLayerTop + else -> colors.backgroundLayerMedium + } Card( onClick = onClick, modifier = Modifier.fillMaxWidth(), shape = shapes.large, - colors = CardDefaults.cardColors( - containerColor = if (isSelected) colors.backgroundLayerTop else colors.backgroundLayerMedium - ), + colors = CardDefaults.cardColors(containerColor = cardBackground), border = BorderStroke( width = if (isSelected) 2.dp else 1.dp, - color = if (isSelected) colors.borderBold else colors.borderDefault + color = when { + isSelected && isDark -> colors.backgroundAccent // green #A7F3D0 in dark + isSelected -> colors.borderBold // grey #A1A1AA in light + else -> colors.borderDefault + } ) ) { Row( @@ -92,27 +105,34 @@ fun FactorCard( Spacer(modifier = Modifier.width(dimensions.spacingMd)) - // Radio selection indicator: filled dark circle + white dot when selected, - // empty light circle with grey ring when unselected. + // Radio selection indicator: + // Light selected: dark filled circle (#09090B) + white inner dot + // Dark selected: green filled circle (#A7F3D0 accent) + dark inner dot + // Unselected: transparent circle with subtle border + val radioFill = when { + isSelected && isDark -> colors.backgroundAccent + isSelected -> colors.backgroundPrimary + else -> colors.backgroundLayerBase + } + val radioBorder = if (isSelected) radioFill else colors.borderDefault + val radioInnerDot = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop + Box( modifier = Modifier .size(20.dp) .border( width = if (isSelected) 0.dp else 1.dp, - color = if (isSelected) colors.backgroundPrimary else colors.borderDefault, + color = radioBorder, shape = shapes.full ) - .background( - color = if (isSelected) colors.backgroundPrimary else colors.backgroundLayerBase, - shape = shapes.full - ), + .background(color = radioFill, shape = shapes.full), contentAlignment = Alignment.Center ) { if (isSelected) { Box( modifier = Modifier .size(8.dp) - .background(color = colors.backgroundLayerTop, shape = shapes.full) + .background(color = radioInnerDot, shape = shapes.full) ) } } diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt index 136114b..98c8196 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt @@ -1,7 +1,6 @@ package com.auth0.android.sample.ui.screens import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets @@ -29,11 +28,9 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import com.auth0.android.sample.ui.components.Auth0LogoHeader import com.auth0.android.sample.ui.components.FactorCard -import com.auth0.android.sample.ui.theme.BackGroundColor -import com.auth0.android.sample.ui.theme.BottomCoolOverlay -import com.auth0.android.sample.ui.theme.BottomWarmOverlay -import com.auth0.android.sample.ui.theme.DarkBackGroundColor +import com.auth0.android.sample.ui.theme.auth0ScreenBackground import com.auth0.universalcomponents.theme.Auth0Theme +import com.auth0.universalcomponents.theme.Auth0Theme.colors private enum class LoginOption { Embedded, Hosted } @@ -54,9 +51,6 @@ fun ChooseSignInScreen( onSettings: () -> Unit = {} ) { var selectedOption by remember { mutableStateOf(null) } - val backgroundBrush = if (isSystemInDarkTheme()) DarkBackGroundColor else BackGroundColor - val isDark = isSystemInDarkTheme() - val colors = Auth0Theme.colors val typography = Auth0Theme.typography val dimensions = Auth0Theme.dimensions val shapes = Auth0Theme.shapes @@ -65,13 +59,7 @@ fun ChooseSignInScreen( Column( modifier = Modifier .fillMaxSize() - .background(backgroundBrush) - .run { - // Layer warm (bottom-left) and cool/lavender (bottom-right) overlays - // to match the Figma diagonal gradient at the bottom of the screen. - if (!isDark) background(BottomWarmOverlay).background(BottomCoolOverlay) - else this - } + .auth0ScreenBackground() .windowInsetsPadding(WindowInsets.navigationBars) ) { // Scrollable main content — weight(1f) leaves room for the pinned Appearance button diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt index e2920e3..20c2cbc 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.unit.dp import com.auth0.android.sample.R import com.auth0.android.sample.ui.components.NavigationGridCard import com.auth0.android.sample.ui.components.SectionHeader +import com.auth0.android.sample.ui.theme.auth0ScreenBackground import com.auth0.universalcomponents.theme.Auth0Theme enum class DashboardDestination(val label: String, val icon: Int) { @@ -60,7 +61,9 @@ fun DashboardScreen( val dimensions = Auth0Theme.dimensions Box( - modifier = Modifier.background(colors.backgroundLayerBase) + modifier = Modifier + .fillMaxSize() + .auth0ScreenBackground() ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt index f907bc7..10c930a 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt @@ -35,7 +35,7 @@ import com.auth0.android.sample.R import com.auth0.android.sample.ui.components.Auth0LogoHeader import com.auth0.android.sample.ui.components.OrDivider import com.auth0.android.sample.ui.components.SectionHeader -import com.auth0.android.sample.ui.theme.BackGroundColor +import com.auth0.android.sample.ui.theme.auth0ScreenBackground import com.auth0.universalcomponents.presentation.ui.components.GradientButton import com.auth0.universalcomponents.theme.Auth0Theme @@ -70,7 +70,7 @@ fun EmbeddedLoginScreen( Column( modifier = Modifier .fillMaxSize() - .background(BackGroundColor) + .auth0ScreenBackground() .padding(horizontal = dimensions.spacingLg), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/ExploreLoginScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/ExploreLoginScreen.kt index 79c2fcd..f4f77f4 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/ExploreLoginScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/ExploreLoginScreen.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.res.painterResource import com.auth0.android.sample.ui.components.Auth0LogoHeader import com.auth0.android.sample.ui.components.FactorCard import com.auth0.android.sample.ui.components.SectionHeader -import com.auth0.android.sample.ui.theme.BackGroundColor +import com.auth0.android.sample.ui.theme.auth0ScreenBackground import com.auth0.universalcomponents.theme.Auth0Theme /** @@ -40,7 +40,7 @@ fun ExploreLoginScreen( Column( modifier = Modifier .fillMaxSize() - .background(BackGroundColor) + .auth0ScreenBackground() .verticalScroll(rememberScrollState()) .padding(horizontal = dimensions.spacingLg), horizontalAlignment = Alignment.CenterHorizontally diff --git a/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt new file mode 100644 index 0000000..9a59d2e --- /dev/null +++ b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt @@ -0,0 +1,29 @@ +package com.auth0.android.sample.ui.theme + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.foundation.background +import com.auth0.universalcomponents.theme.Auth0Theme + +/** + * Applies the Auth0 screen background to this modifier. + * + * Light theme: vertical gradient [BackGroundColor] + * Dark theme: flat [DarkBackGroundColor] (#09090B) + * + * Theme mode is detected from [Auth0Theme.colors] so it correctly follows the in-app + * theme switcher, not just the OS dark mode setting. + */ +@Composable +fun Modifier.auth0ScreenBackground(): Modifier { + val colors = Auth0Theme.colors + // backgroundLayerBase is #09090B (red≈0.035) in dark, #F4F4F5 (red≈0.957) in light. + val isDark = colors.backgroundLayerBase.red < 0.1f + val brush = if (isDark) DarkBackGroundColor else BackGroundColor + return this + .background(brush) + .run { + if (!isDark) background(BottomWarmOverlay).background(BottomCoolOverlay) + else this + } +} diff --git a/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt b/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt index ed84dbf..41c31d9 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/theme/Color.kt @@ -15,14 +15,6 @@ val Pink40 = Color(0xFF7D5260) /** * Light theme background — vertical base gradient. * - * Sampled directly from the Figma design: - * #F4F4F5 — top of screen through end of cards (exact sample) - * #EDEBF1 — just below the cards (slight lavender tint, exact sample) - * #EBE1E4 — bottom centre (average of bottom-left #E9D7D4 warm and bottom-right #EDEBF4 lavender) - * - * Note: the bottom-left (#E9D7D4, warm) vs bottom-right (#EDEBF4, lavender) split - * is captured by a separate diagonal overlay brush — see [BottomWarmOverlay] and - * [BottomCoolOverlay] used in ChooseSignInScreen. */ val BackGroundColor = Brush.linearGradient( colorStops = arrayOf( @@ -35,7 +27,6 @@ val BackGroundColor = Brush.linearGradient( ) /** - * Warm (pinkish) overlay concentrated at the bottom-left corner. * Blended on top of [BackGroundColor] to reproduce the #E9D7D4 bottom-left sample. */ val BottomWarmOverlay = Brush.radialGradient( @@ -45,7 +36,6 @@ val BottomWarmOverlay = Brush.radialGradient( ) /** - * Cool (lavender) overlay concentrated at the bottom-right corner. * Blended on top of [BackGroundColor] to reproduce the #EDEBF4 bottom-right sample. */ val BottomCoolOverlay = Brush.radialGradient( @@ -55,21 +45,9 @@ val BottomCoolOverlay = Brush.radialGradient( ) /** - * Dark theme background gradient. - * - * Mirrors the light gradient: flat near-black base (#09090B) for the top 75%, - * then a warm amber/cream equivalent fades in at the bottom 25%. + * Dark theme background — flat #09090B (Auth0 backgroundLayerBase dark). * - * 0% #09090B — Auth0 backgroundLayerBase dark (near-black) - * 75% #0E0C09 — barely warm, still reads near-black - * 100% #221608 — dark warm amber at very bottom */ val DarkBackGroundColor = Brush.linearGradient( - colorStops = arrayOf( - 0.00f to Color(0xFF09090B), - 0.75f to Color(0xFF0E0C09), - 1.00f to Color(0xFF221608) - ), - start = Offset(0f, 0f), - end = Offset(0f, Float.POSITIVE_INFINITY) + colors = listOf(Color(0xFF09090B), Color(0xFF09090B)) ) From 0a982e0f04bfbeb3aaaa1223a0cce63a1a8dd8f4 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 17:29:46 +0530 Subject: [PATCH 3/6] Added back arrow to embedded login screen --- .../sample/ui/screens/ChooseSignInScreen.kt | 5 +++-- .../sample/ui/screens/EmbeddedLoginScreen.kt | 15 +++++++++++++++ .../android/sample/ui/theme/BackgroundModifier.kt | 1 - 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt index 98c8196..5cb0c38 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -60,9 +61,9 @@ fun ChooseSignInScreen( modifier = Modifier .fillMaxSize() .auth0ScreenBackground() + .statusBarsPadding() .windowInsetsPadding(WindowInsets.navigationBars) ) { - // Scrollable main content — weight(1f) leaves room for the pinned Appearance button Column( modifier = Modifier .weight(1f) @@ -74,7 +75,7 @@ fun ChooseSignInScreen( Auth0LogoHeader() - Spacer(modifier = Modifier.height(dimensions.spacingXxl * 4)) + Spacer(modifier = Modifier.height(dimensions.spacingXxl * 2)) Text( text = "Choose how to sign in", diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt index 10c930a..0f10060 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt @@ -4,13 +4,17 @@ import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image import androidx.compose.foundation.background 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.statusBarsPadding import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -71,9 +75,20 @@ fun EmbeddedLoginScreen( modifier = Modifier .fillMaxSize() .auth0ScreenBackground() + .statusBarsPadding() .padding(horizontal = dimensions.spacingLg), horizontalAlignment = Alignment.CenterHorizontally ) { + Row(modifier = Modifier.fillMaxWidth()) { + IconButton(onClick = onBack) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back", + tint = colors.textBold + ) + } + } + Auth0LogoHeader() Spacer(modifier = Modifier.height(dimensions.spacingXxl)) diff --git a/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt index 9a59d2e..53c2142 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt @@ -17,7 +17,6 @@ import com.auth0.universalcomponents.theme.Auth0Theme @Composable fun Modifier.auth0ScreenBackground(): Modifier { val colors = Auth0Theme.colors - // backgroundLayerBase is #09090B (red≈0.035) in dark, #F4F4F5 (red≈0.957) in light. val isDark = colors.backgroundLayerBase.red < 0.1f val brush = if (isDark) DarkBackGroundColor else BackGroundColor return this From 445a4420a991d091b4a1dc4d8a89ee290ab296e4 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 18:09:36 +0530 Subject: [PATCH 4/6] Fixed the dark theme mismatches in screens --- .../ui/components/NavigationGridCard.kt | 4 ++-- .../sample/ui/screens/AppearanceScreen.kt | 20 ++++++++++++++----- .../sample/ui/screens/DashboardScreen.kt | 4 +++- .../sample/ui/screens/EmbeddedLoginScreen.kt | 16 +++++++++++---- .../sample/ui/viewmodels/AuthViewModel.kt | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/NavigationGridCard.kt b/app/src/main/java/com/auth0/android/sample/ui/components/NavigationGridCard.kt index d1b499d..b11d12b 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/NavigationGridCard.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/NavigationGridCard.kt @@ -51,8 +51,8 @@ fun NavigationGridCard( .clickable { onClick() }, shape = shapes.extraLarge, colors = CardDefaults.cardColors(containerColor = colors.backgroundLayerTop), - border = BorderStroke(1.dp, colors.borderBold), - elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + border = BorderStroke(1.dp, colors.borderDefault), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt index 142c835..9cc4ae9 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt @@ -39,13 +39,23 @@ fun AppearanceScreen( onBack: () -> Unit, appearanceViewModel: AppearanceViewModel ) { + val selectedIndex by appearanceViewModel.selectedIndex.collectAsStateWithLifecycle() + val previewOption = appearanceViewModel.themeOptions.getOrElse(selectedIndex) { + appearanceViewModel.themeOptions[0] + } + + // Wrap in a local Auth0Theme so the screen previews the selected theme immediately, + // while the global theme (in MainActivity) only updates when "Update Theme" is tapped. + Auth0Theme( + configuration = previewOption.configuration, + darkTheme = previewOption.darkTheme + ) { val colors = Auth0Theme.colors val typography = Auth0Theme.typography val shapes = Auth0Theme.shapes val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes - - val selectedIndex by appearanceViewModel.selectedIndex.collectAsStateWithLifecycle() + val isDark = colors.backgroundLayerBase.red < 0.1f Scaffold( topBar = { @@ -108,7 +118,7 @@ fun AppearanceScreen( selected = selectedIndex == index, onClick = { appearanceViewModel.selectTheme(index) }, colors = RadioButtonDefaults.colors( - selectedColor = colors.backgroundPrimary, + selectedColor = if (isDark) colors.backgroundAccent else colors.backgroundPrimary, unselectedColor = colors.borderDefault ) ) @@ -124,7 +134,7 @@ fun AppearanceScreen( } } - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.height(dimensions.spacingLg)) GradientButton( modifier = Modifier @@ -142,7 +152,7 @@ fun AppearanceScreen( ) } - Spacer(modifier = Modifier.height(dimensions.spacingLg)) } } + } // Auth0Theme } diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt index 20c2cbc..bfca1d2 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt @@ -85,7 +85,7 @@ fun DashboardScreen( contentPadding = PaddingValues(0.dp), horizontalArrangement = Arrangement.spacedBy(13.dp), verticalArrangement = Arrangement.spacedBy(dimensions.spacingMd), - modifier = Modifier.weight(1f) + modifier = Modifier ) { items(DashboardDestination.entries.toList()) { destination -> NavigationGridCard( @@ -96,6 +96,8 @@ fun DashboardScreen( } } + Spacer(modifier = Modifier.height(dimensions.spacingLg)) + TextButton(onClick = onLogout) { Text( text = "Log out", diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt index 0f10060..0f8ba05 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt @@ -66,6 +66,8 @@ fun EmbeddedLoginScreen( val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes val shapes = Auth0Theme.shapes + val isDark = colors.backgroundLayerBase.red < 0.1f + val fieldFocusedBorder = if (isDark) colors.backgroundAccent else colors.backgroundPrimary var email by rememberSaveable { mutableStateOf("") } var password by rememberSaveable { mutableStateOf("") } @@ -148,10 +150,13 @@ fun EmbeddedLoginScreen( textStyle = typography.body, shape = shapes.medium, colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = colors.backgroundPrimary, + focusedBorderColor = fieldFocusedBorder, unfocusedBorderColor = colors.borderDefault, focusedContainerColor = colors.backgroundLayerTop, - unfocusedContainerColor = colors.backgroundLayerTop + unfocusedContainerColor = colors.backgroundLayerTop, + focusedTextColor = colors.textBold, + unfocusedTextColor = colors.textBold, + cursorColor = fieldFocusedBorder ), singleLine = true ) @@ -193,10 +198,13 @@ fun EmbeddedLoginScreen( } }, colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = colors.backgroundPrimary, + focusedBorderColor = fieldFocusedBorder, unfocusedBorderColor = colors.borderDefault, focusedContainerColor = colors.backgroundLayerTop, - unfocusedContainerColor = colors.backgroundLayerTop + unfocusedContainerColor = colors.backgroundLayerTop, + focusedTextColor = colors.textBold, + unfocusedTextColor = colors.textBold, + cursorColor = fieldFocusedBorder ), singleLine = true ) diff --git a/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt b/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt index 1102e7a..35da684 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt @@ -60,7 +60,7 @@ class AuthViewModel : ViewModel() { _authState.value = AuthState.Authenticated(credentials) } catch (e: AuthenticationException) { if (e.isBrowserAppNotAvailable || e.isCanceled) { - Log.d("TAG", "login: User cancelled or browser not available") + Log.e("TAG", "login: User cancelled or browser not available") _authState.value = AuthState.Idle } else { Log.e("TAG", "login: ${e.printStackTrace()}") From cc0dc7769da7bf33fd4dd06a14f9ea0560cbd004 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 22:04:14 +0530 Subject: [PATCH 5/6] Addresed review comments --- .../com/auth0/android/sample/MainActivity.kt | 23 +++++++++--- .../sample/ui/components/Auth0LogoHeader.kt | 6 ++-- .../sample/ui/components/FactorCard.kt | 6 ++-- .../sample/ui/screens/AppearanceScreen.kt | 3 +- .../sample/ui/screens/ChooseSignInScreen.kt | 1 - .../sample/ui/screens/DashboardScreen.kt | 3 +- .../sample/ui/screens/EmbeddedLoginScreen.kt | 35 ++++++++++++------- .../sample/ui/theme/BackgroundModifier.kt | 12 +++++-- .../sample/ui/viewmodels/AuthViewModel.kt | 4 ++- 9 files changed, 60 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/com/auth0/android/sample/MainActivity.kt b/app/src/main/java/com/auth0/android/sample/MainActivity.kt index b81b7f7..e7e2b72 100644 --- a/app/src/main/java/com/auth0/android/sample/MainActivity.kt +++ b/app/src/main/java/com/auth0/android/sample/MainActivity.kt @@ -170,11 +170,24 @@ fun SampleApp( composable { val context = LocalContext.current - ChooseSignInScreen( - onHostedLogin = { authViewModel.login(context, webAuthProvider) }, - onEmbeddedLogin = { navController.navigate(AppRoute.EmbeddedLogin) }, - onSettings = { navController.navigate(AppRoute.Appearance) } - ) + val snackbarHostState = remember { SnackbarHostState() } + + LaunchedEffect(Unit) { + authViewModel.loginError.collect { message -> + snackbarHostState.showSnackbar(message) + } + } + + Scaffold( + snackbarHost = { SnackbarHost(snackbarHostState) }, + containerColor = androidx.compose.ui.graphics.Color.Transparent + ) { _ -> + ChooseSignInScreen( + onHostedLogin = { authViewModel.login(context, webAuthProvider) }, + onEmbeddedLogin = { navController.navigate(AppRoute.EmbeddedLogin) }, + onSettings = { navController.navigate(AppRoute.Appearance) } + ) + } } composable { diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt b/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt index ad5b302..248d0af 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/Auth0LogoHeader.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import com.auth0.android.sample.R +import com.auth0.android.sample.ui.theme.isAuth0DarkTheme import com.auth0.universalcomponents.theme.Auth0Theme /** @@ -25,10 +26,7 @@ fun Auth0LogoHeader( ) { val dimensions = Auth0Theme.dimensions val colors = Auth0Theme.colors - // ic_auth0.xml paths are hardcoded #09090B — invisible on dark backgrounds. - // Detect dark mode from Auth0Theme tokens (not isSystemInDarkTheme) so the in-app - // theme switcher is respected. Light: preserve SVG fill. Dark: tint white (#FAFAFA). - val logoTint = if (colors.backgroundLayerBase.red < 0.1f) colors.textBold else Color.Unspecified + val logoTint = if (isAuth0DarkTheme()) colors.textBold else Color.Unspecified Spacer(modifier = Modifier.height(dimensions.spacingXl)) diff --git a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt index 439cb87..3f644b2 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/components/FactorCard.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.dp +import com.auth0.android.sample.ui.theme.isAuth0DarkTheme import com.auth0.universalcomponents.theme.Auth0Theme /** @@ -47,10 +48,7 @@ fun FactorCard( val shapes = Auth0Theme.shapes val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes - // Detect current theme from Auth0Theme tokens (not isSystemInDarkTheme) so it - // respects the app's in-app theme switcher, not just the OS dark mode setting. - // backgroundLayerBase is #09090B (dark) vs #F4F4F5 (light) — red channel distinguishes them. - val isDark = colors.backgroundLayerBase.red < 0.1f + val isDark = isAuth0DarkTheme() // Light: selected=white (layerTop), unselected=near-white (layerMedium) // Dark: both cards use layerMedium (#27272A); selection is shown via border only diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt index 9cc4ae9..6e58c7a 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/AppearanceScreen.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.auth0.android.sample.ui.viewmodels.AppearanceViewModel import com.auth0.universalcomponents.presentation.ui.components.GradientButton import com.auth0.universalcomponents.presentation.ui.components.TopBar +import com.auth0.android.sample.ui.theme.isAuth0DarkTheme import com.auth0.universalcomponents.theme.Auth0Theme /** @@ -55,7 +56,7 @@ fun AppearanceScreen( val shapes = Auth0Theme.shapes val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes - val isDark = colors.backgroundLayerBase.red < 0.1f + val isDark = isAuth0DarkTheme() Scaffold( topBar = { diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt index 5cb0c38..b2f2dd5 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/ChooseSignInScreen.kt @@ -1,6 +1,5 @@ package com.auth0.android.sample.ui.screens -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt index bfca1d2..3697f54 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/DashboardScreen.kt @@ -84,8 +84,7 @@ fun DashboardScreen( columns = GridCells.Fixed(2), contentPadding = PaddingValues(0.dp), horizontalArrangement = Arrangement.spacedBy(13.dp), - verticalArrangement = Arrangement.spacedBy(dimensions.spacingMd), - modifier = Modifier + verticalArrangement = Arrangement.spacedBy(dimensions.spacingMd) ) { items(DashboardDestination.entries.toList()) { destination -> NavigationGridCard( diff --git a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt index 0f8ba05..cc55b89 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/screens/EmbeddedLoginScreen.kt @@ -2,7 +2,6 @@ package com.auth0.android.sample.ui.screens import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -13,16 +12,16 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -31,6 +30,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation @@ -38,8 +38,8 @@ import androidx.compose.ui.unit.dp import com.auth0.android.sample.R import com.auth0.android.sample.ui.components.Auth0LogoHeader import com.auth0.android.sample.ui.components.OrDivider -import com.auth0.android.sample.ui.components.SectionHeader import com.auth0.android.sample.ui.theme.auth0ScreenBackground +import com.auth0.android.sample.ui.theme.isAuth0DarkTheme import com.auth0.universalcomponents.presentation.ui.components.GradientButton import com.auth0.universalcomponents.theme.Auth0Theme @@ -66,7 +66,7 @@ fun EmbeddedLoginScreen( val dimensions = Auth0Theme.dimensions val sizes = Auth0Theme.sizes val shapes = Auth0Theme.shapes - val isDark = colors.backgroundLayerBase.red < 0.1f + val isDark = isAuth0DarkTheme() val fieldFocusedBorder = if (isDark) colors.backgroundAccent else colors.backgroundPrimary var email by rememberSaveable { mutableStateOf("") } @@ -95,7 +95,13 @@ fun EmbeddedLoginScreen( Spacer(modifier = Modifier.height(dimensions.spacingXxl)) - SectionHeader(title = "Login or Signup to continue") + Text( + text = "Login or Signup to continue", + style = typography.displayMedium, + color = colors.textBold, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) Spacer(modifier = Modifier.height(dimensions.spacingLg)) @@ -106,7 +112,10 @@ fun EmbeddedLoginScreen( .fillMaxWidth() .height(sizes.buttonHeight), shape = shapes.large, - border = BorderStroke(1.dp, colors.borderDefault) + border = BorderStroke(1.dp, colors.borderDefault), + colors = ButtonDefaults.outlinedButtonColors( + containerColor = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop + ) ) { Image( painter = painterResource(id = R.drawable.ic_google), @@ -148,12 +157,12 @@ fun EmbeddedLoginScreen( ) }, textStyle = typography.body, - shape = shapes.medium, + shape = shapes.large, colors = OutlinedTextFieldDefaults.colors( focusedBorderColor = fieldFocusedBorder, unfocusedBorderColor = colors.borderDefault, - focusedContainerColor = colors.backgroundLayerTop, - unfocusedContainerColor = colors.backgroundLayerTop, + focusedContainerColor = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop, + unfocusedContainerColor = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop, focusedTextColor = colors.textBold, unfocusedTextColor = colors.textBold, cursorColor = fieldFocusedBorder @@ -183,7 +192,7 @@ fun EmbeddedLoginScreen( ) }, textStyle = typography.body, - shape = shapes.medium, + shape = shapes.large, visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), trailingIcon = { @@ -200,8 +209,8 @@ fun EmbeddedLoginScreen( colors = OutlinedTextFieldDefaults.colors( focusedBorderColor = fieldFocusedBorder, unfocusedBorderColor = colors.borderDefault, - focusedContainerColor = colors.backgroundLayerTop, - unfocusedContainerColor = colors.backgroundLayerTop, + focusedContainerColor = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop, + unfocusedContainerColor = if (isDark) colors.backgroundLayerMedium else colors.backgroundLayerTop, focusedTextColor = colors.textBold, unfocusedTextColor = colors.textBold, cursorColor = fieldFocusedBorder diff --git a/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt index 53c2142..5be5c2b 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/theme/BackgroundModifier.kt @@ -5,6 +5,15 @@ import androidx.compose.ui.Modifier import androidx.compose.foundation.background import com.auth0.universalcomponents.theme.Auth0Theme +/** + * Returns true when the active Auth0Theme is in dark mode. + * + * Centralises the dark-mode check so it only needs updating in one place + * if the underlying token changes. + */ +@Composable +fun isAuth0DarkTheme(): Boolean = Auth0Theme.colors.backgroundLayerBase.red < 0.1f + /** * Applies the Auth0 screen background to this modifier. * @@ -16,8 +25,7 @@ import com.auth0.universalcomponents.theme.Auth0Theme */ @Composable fun Modifier.auth0ScreenBackground(): Modifier { - val colors = Auth0Theme.colors - val isDark = colors.backgroundLayerBase.red < 0.1f + val isDark = isAuth0DarkTheme() val brush = if (isDark) DarkBackGroundColor else BackGroundColor return this .background(brush) diff --git a/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt b/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt index 35da684..8fc0bf7 100644 --- a/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt +++ b/app/src/main/java/com/auth0/android/sample/ui/viewmodels/AuthViewModel.kt @@ -60,10 +60,12 @@ class AuthViewModel : ViewModel() { _authState.value = AuthState.Authenticated(credentials) } catch (e: AuthenticationException) { if (e.isBrowserAppNotAvailable || e.isCanceled) { - Log.e("TAG", "login: User cancelled or browser not available") + Log.i("TAG", "login: User cancelled or browser not available") + _loginError.send("User cancelled or browser not available\"") _authState.value = AuthState.Idle } else { Log.e("TAG", "login: ${e.printStackTrace()}") + _loginError.send(e.message ?: "An unknown error occurred") _authState.value = AuthState.Error(e.message ?: "An unknown error occurred") } } From ae9875b5493ec05811165cf1410529ed162f2510 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 23 Mar 2026 15:25:47 +0530 Subject: [PATCH 6/6] Updated dependebot frequency --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d1a3f4b..ef867bc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,6 +3,6 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" + interval: "daily" commit-message: prefix: "chore(deps)"