Skip to content

[POC] Link inline 2FA #10916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.stripe.android.financialconnections.ui.theme

import androidx.annotation.RestrictTo
import androidx.compose.runtime.Composable
import com.stripe.android.financialconnections.ui.theme.FinancialConnectionsTheme.colors
import com.stripe.android.uicore.StripeTheme
import com.stripe.android.uicore.StripeThemeDefaults

@Composable
internal fun StripeThemeForConnections(
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun StripeThemeForConnections(
content: @Composable () -> Unit
) {
// Financial Connections does not currently support dark mode.
Expand Down
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ android.nonTransitiveRClass=true
android.useAndroidX=true
android.experimental.androidTest.numManagedDeviceShards=6

kotlin.daemon.jvmargs=-Xmx8g
org.gradle.jvmargs=-Xmx8g -Dfile.encoding=UTF-8

# Update StripeSdkVersion.VERSION_NAME when publishing a new release
VERSION_NAME=21.16.0
1 change: 1 addition & 0 deletions paymentsheet-example/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<activity android:name="com.stripe.android.paymentsheet.example.playground.activity.FawryActivity" />
<activity android:name="com.stripe.android.paymentsheet.example.playground.activity.CustomPaymentMethodActivity" />
<activity android:name="com.stripe.android.paymentsheet.example.playground.embedded.EmbeddedPlaygroundActivity" />

<activity
android:name="com.stripe.android.paymentsheet.example.playground.PaymentSheetPlaygroundActivity"
android:theme="@style/AppTheme.NoActionBar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,14 @@ internal class PaymentSheetPlaygroundActivity :
)
}

PlaygroundConfigurationData.IntegrationType.WalletsButton -> {
// Using flow controller to demonstrate wallet buttons
FlowControllerUi(
flowController = flowController,
playgroundState = playgroundState,
)
}

else -> Unit
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ data class PlaygroundConfigurationData(
@SerialName("Embedded")
Embedded,

@SerialName("walletsButton")
WalletsButton,

@SerialName("CustomerSheet")
CustomerSheet;

fun isPaymentFlow(): Boolean {
return this in setOf(PaymentSheet, FlowController, Embedded)
return this in setOf(PaymentSheet, FlowController, Embedded, WalletsButton)
}

fun isCustomerFlow(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ private fun IntegrationTypeConfigurableSetting(
name = "Customer Sheet",
value = PlaygroundConfigurationData.IntegrationType.CustomerSheet
),
PlaygroundSettingDefinition.Displayable.Option(
name = "Wallets Button",
value = PlaygroundConfigurationData.IntegrationType.WalletsButton
),
),
value = configurationData.integrationType
) { integrationType ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.stripe.android.link.ui.verification

import android.os.Parcelable
import androidx.compose.runtime.Immutable
import com.stripe.android.core.strings.ResolvableString
import kotlinx.parcelize.Parcelize

@Immutable
@Parcelize
internal data class VerificationViewState(
val isProcessing: Boolean,
val requestFocus: Boolean,
Expand All @@ -13,4 +16,4 @@ internal data class VerificationViewState(
val redactedPhoneNumber: String,
val email: String,
val isDialog: Boolean
)
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.stripe.android.link.ui.wallet

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import com.stripe.android.link.theme.DefaultLinkTheme
import com.stripe.android.link.theme.LinkTheme
import com.stripe.android.link.theme.StripeThemeForLink
import com.stripe.android.link.ui.LinkSpinner
import com.stripe.android.link.ui.verification.VERIFICATION_OTP_TAG
import com.stripe.android.link.ui.verification.VerificationViewState
import com.stripe.android.uicore.elements.OTPElement
import com.stripe.android.uicore.elements.OTPElementColors
import com.stripe.android.uicore.elements.OTPElementUI

@Composable
internal fun LinkVerificationSection(
verificationState: VerificationViewState,
otpElement: OTPElement,
modifier: Modifier = Modifier
) {
DefaultLinkTheme {
Column(
modifier = modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.border(
width = 1.dp,
color = LinkTheme.colors.borderDefault,
shape = RoundedCornerShape(8.dp)
)
.background(
color = LinkTheme.colors.surfacePrimary,
shape = RoundedCornerShape(8.dp)
)
.padding(10.dp)
) {
// Compact verification message
Text(
text = "Verify: ${verificationState.redactedPhoneNumber}",
style = LinkTheme.typography.caption,
color = LinkTheme.colors.textPrimary,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 6.dp)
)

// OTP input with minimal padding
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.padding(vertical = 4.dp)
) {
StripeThemeForLink {
OTPElementUI(
enabled = !verificationState.isProcessing,
element = otpElement,
otpInputPlaceholder = " ",
middleSpacing = 6.dp, // Reduced spacing between digits
modifier = Modifier
.testTag(VERIFICATION_OTP_TAG)
.alpha(if (verificationState.isProcessing) 0.5f else 1f),
colors = OTPElementColors(
selectedBorder = LinkTheme.colors.borderSelected,
placeholder = LinkTheme.colors.textPrimary,
background = LinkTheme.colors.surfaceSecondary
),
)
}

// Smaller loading indicator
if (verificationState.isProcessing) {
LinkSpinner(
modifier = Modifier
.size(28.dp)
.zIndex(1f),
strokeWidth = 2.dp
)
}
}

// Compact error message
verificationState.errorMessage?.let { error ->
Text(
text = error.resolve(LocalContext.current),
style = LinkTheme.typography.caption,
color = LinkTheme.colors.textCritical,
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp)
)
}
}
}
}
Loading
Loading