Skip to content

Commit

Permalink
[Identity] Butter M1 UX tweaks (#7638)
Browse files Browse the repository at this point in the history
  • Loading branch information
ccen-stripe committed Nov 17, 2023
1 parent 5635be9 commit f42dbe7
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 69 deletions.
14 changes: 14 additions & 0 deletions identity/api/identity.api
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,27 @@ public final class com/stripe/android/identity/ui/ComposableSingletons$BottomShe
public final fun getLambda-2$identity_release ()Lkotlin/jvm/functions/Function2;
}

public final class com/stripe/android/identity/ui/ComposableSingletons$ConsentLinesKt {
public static final field INSTANCE Lcom/stripe/android/identity/ui/ComposableSingletons$ConsentLinesKt;
public static field lambda-1 Lkotlin/jvm/functions/Function2;
public fun <init> ()V
public final fun getLambda-1$identity_release ()Lkotlin/jvm/functions/Function2;
}

public final class com/stripe/android/identity/ui/ComposableSingletons$ConsentScreenKt {
public static final field INSTANCE Lcom/stripe/android/identity/ui/ComposableSingletons$ConsentScreenKt;
public static field lambda-1 Lkotlin/jvm/functions/Function2;
public fun <init> ()V
public final fun getLambda-1$identity_release ()Lkotlin/jvm/functions/Function2;
}

public final class com/stripe/android/identity/ui/ComposableSingletons$ConsentWelcomeHeaderKt {
public static final field INSTANCE Lcom/stripe/android/identity/ui/ComposableSingletons$ConsentWelcomeHeaderKt;
public static field lambda-1 Lkotlin/jvm/functions/Function2;
public fun <init> ()V
public final fun getLambda-1$identity_release ()Lkotlin/jvm/functions/Function2;
}

public final class com/stripe/android/identity/ui/ComposableSingletons$DebugScreenKt {
public static final field INSTANCE Lcom/stripe/android/identity/ui/ComposableSingletons$DebugScreenKt;
public static field lambda-1 Lkotlin/jvm/functions/Function3;
Expand Down
15 changes: 15 additions & 0 deletions identity/res/drawable/stripe_ellipsis_icon.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="4dp"
android:viewportWidth="16"
android:viewportHeight="4">
<path
android:pathData="M2,2m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:fillColor="#EBEEF1"/>
<path
android:pathData="M8,2m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:fillColor="#C0C8D2"/>
<path
android:pathData="M14,2m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:fillColor="#87909F"/>
</vector>
2 changes: 2 additions & 0 deletions identity/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

<color name="stripe_selfie_warmup_icon_tint">#F7FAFC</color>
<color name="stripe_doc_warmup_icon_tint">#F7FAFC</color>

<color name="stripe_html_line">#D8DEE4</color>
</resources>
2 changes: 2 additions & 0 deletions identity/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@

<color name="stripe_selfie_warmup_icon_tint">#1A1B25</color>
<color name="stripe_doc_warmup_icon_tint">#1A1B25</color>

<color name="stripe_html_line">#687385</color>
</resources>
6 changes: 6 additions & 0 deletions identity/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<resources>
<!-- title for accepted types of ids -->
<string name="stripe_accepted_forms_of_id">Accepted forms of ID</string>
<!-- title for accepted types of ids prefix -->
<string name="stripe_accepted_forms_of_id_include">Accepted forms of ID include</string>
<!-- Opens the app's settings in the Settings app -->
<string name="stripe_app_settings">App Settings</string>
<!-- Description of back of driver's license image -->
Expand Down Expand Up @@ -47,6 +49,8 @@
<string name="stripe_description_dispute_protection">dispute_protection icon</string>
<!-- Content description for document icon -->
<string name="stripe_description_document">document icon</string>
<!-- Content description for ellipsis icon -->
<string name="stripe_description_ellipsis">ellipsis icon</string>
<!-- Content description for exclamation icon -->
<string name="stripe_description_exclamation">exclamation icon</string>
<!-- Content description for back button -->
Expand Down Expand Up @@ -111,6 +115,8 @@
<string name="stripe_id_card">ID</string>
<!-- Label for ID number section -->
<string name="stripe_id_number">ID Number</string>
<!-- I'm ready button text -->
<string name="stripe_im_ready">I\'m ready</string>
<!-- An error message. -->
<string name="stripe_incomplete_id_number">The ID number you entered is incomplete.</string>
<!-- Label for the ID field to collect individual CPF for Brazilian ID -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
Expand All @@ -22,9 +23,11 @@ import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
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 androidx.lifecycle.viewmodel.compose.viewModel
import com.stripe.android.identity.R
import com.stripe.android.identity.networking.models.VerificationPageIconType
Expand All @@ -34,6 +37,7 @@ import com.stripe.android.identity.networking.models.getContentDescriptionId
import com.stripe.android.identity.networking.models.getResourceId
import com.stripe.android.identity.viewmodel.BottomSheetViewModel
import com.stripe.android.uicore.text.Html
import java.util.regex.Pattern

@Composable
@ExperimentalMaterialApi
Expand Down Expand Up @@ -111,25 +115,62 @@ private fun BottomSheetLine(line: VerificationPageStaticContentBottomSheetLineCo
) {
Text(
text = line.title,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(
bottom = 4.dp
)
)
Html(
html = line.content,
color = MaterialTheme.colors.onSurface.copy(
alpha = 0.6f
),
urlSpanStyle = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colors.secondary
)
)

line.content.tryParseUl()?.let { bulletStrings ->
// [HTML] uses HtmlCompat.fromHtml, which automatically adds an additional line break for <li> items.
// We would like to build our line break instead.
for (bulletString in bulletStrings) {
Text(
modifier = Modifier.padding(bottom = 2.dp),
text = "$bulletString",
color = MaterialTheme.colors.onSurface,
style = LocalTextStyle.current.merge(
lineHeight = 20.sp
)
)
}
} ?: run {
Html(
html = line.content,
color = MaterialTheme.colors.onSurface,
style = LocalTextStyle.current.merge(
lineHeight = 20.sp
),
urlSpanStyle = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colors.onSurface
)
)
}
}
}
}

private fun String.tryParseUl(): List<String>? {
val trimmed = this.trim()
// Detect if string is an unordered HTML list
val ulPattern = Pattern.compile("^<ul>.*</ul>$", Pattern.DOTALL)
val ulMatcher = ulPattern.matcher(trimmed)
if (!ulMatcher.find()) {
return null
}

// Extract list items
val items: MutableList<String> = mutableListOf()
val liPattern = Pattern.compile("<li>(.*?)</li>", Pattern.DOTALL)
val liMatcher = liPattern.matcher(trimmed)

while (liMatcher.find()) {
items.add(requireNotNull(liMatcher.group(1)))
}
return items
}

@Preview
@Composable
@ExperimentalMaterialApi
Expand All @@ -153,8 +194,14 @@ internal fun ButtonSheetPreview() {
VerificationPageStaticContentBottomSheetLineContent(
icon = VerificationPageIconType.CLOUD,
title = "cloud line",
content = "cloud line content with another " +
content = "Drivers license cloud line content with another " +
"<a href='https://stripe.com'>link</a>, with multiline content"
),
VerificationPageStaticContentBottomSheetLineContent(
icon = VerificationPageIconType.WALLET,
title = "bullets line",
content = "<ul><li>Drivers license</li><li>Passport</li><li>National ID</li>" +
"<li>Valid government-issued identification that clearly shows your face</li><ul>"
)
)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package com.stripe.android.identity.ui

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
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.stripe.android.identity.R
import com.stripe.android.identity.networking.models.VerificationPageIconType
import com.stripe.android.identity.networking.models.VerificationPageStaticConsentLineContent
import com.stripe.android.identity.networking.models.VerificationPageStaticContentBottomSheetContent
import com.stripe.android.identity.networking.models.getContentDescriptionId
Expand All @@ -33,7 +36,11 @@ internal fun ConsentLines(
Row(
modifier = Modifier
.testTag(CONSENT_LINE_TAG)
.padding(top = dimensionResource(id = R.dimen.stripe_item_vertical_margin))
.padding(
top = dimensionResource(id = R.dimen.stripe_item_vertical_margin),
start = dimensionResource(id = R.dimen.stripe_page_horizontal_margin),
end = dimensionResource(id = R.dimen.stripe_page_horizontal_margin)
)
) {
Image(
painter = painterResource(id = line.icon.getResourceId()),
Expand All @@ -44,18 +51,50 @@ internal fun ConsentLines(
)
BottomSheetHTML(
html = line.content,
color = MaterialTheme.colors.onSurface.copy(
alpha = 0.6f
),
color = colorResource(id = R.color.stripe_html_line),
style = LocalTextStyle.current.merge(fontSize = 16.sp),
bottomSheets = bottomSheets,
urlSpanStyle = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colors.secondary
color = colorResource(id = R.color.stripe_html_line)
)
)
}
}
}

internal const val CONSENT_LINE_TAG = "consentLineTag"

@Preview
@Composable
@ExperimentalMaterialApi
internal fun ConsentLinePreview() {
IdentityPreview {
Column {
ConsentLines(
lines = listOf(
VerificationPageStaticConsentLineContent(
icon = VerificationPageIconType.PHONE,
content = "This is the line content with phone icon"
),
VerificationPageStaticConsentLineContent(
icon = VerificationPageIconType.CAMERA,
content = "This is the line content with camera icon"
),
VerificationPageStaticConsentLineContent(
icon = VerificationPageIconType.CLOUD,
content = "This is the line content with cloud icon and a " +
"<a href='https://stripe.com'>web link</a>"
),
VerificationPageStaticConsentLineContent(
icon = VerificationPageIconType.WALLET,
content = "This is the line content with wallet icon and a <a " +
"href='stripe_bottomsheet://open/consent_verification_data'>" +
"bottomsheet link</a>"
)
),
bottomSheets = mapOf()
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
Expand All @@ -21,6 +20,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
Expand Down Expand Up @@ -168,10 +168,10 @@ private fun SuccessUI(
.semantics {
testTag = PRIVACY_POLICY_TAG
},
color = MaterialTheme.colors.onBackground,
color = colorResource(id = R.color.stripe_html_line),
urlSpanStyle = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colors.secondary
color = colorResource(id = R.color.stripe_html_line)
)
)

Expand All @@ -196,7 +196,7 @@ private fun SuccessUI(
onConsentAgreed()
}

LoadingButton(
LoadingTextButton(
modifier = Modifier
.semantics { testTag = DECLINE_BUTTON_TAG },
text = consentPage.declineButtonText.uppercase(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package com.stripe.android.identity.ui
import android.net.Uri
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
Expand All @@ -21,6 +23,7 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.stripe.android.identity.R
Expand Down Expand Up @@ -72,11 +75,11 @@ internal fun ConsentWelcomeHeader(
)
}
Image(
painter = painterResource(id = R.drawable.stripe_plus_icon),
painter = painterResource(id = R.drawable.stripe_ellipsis_icon),
modifier = Modifier
.width(16.dp)
.height(16.dp),
contentDescription = stringResource(id = R.string.stripe_description_plus)
contentDescription = stringResource(id = R.string.stripe_description_ellipsis)
)

Image(
Expand Down Expand Up @@ -106,3 +109,19 @@ internal fun ConsentWelcomeHeader(

)
}

@Preview
@Composable
@ExperimentalMaterialApi
internal fun ConsentWelcomeHeaderPreview() {
IdentityPreview {
Column {
ConsentWelcomeHeader(
modifier = Modifier,
merchantLogoUri = Uri.EMPTY,
title = "TEST TITLE",
showLogos = true
)
}
}
}
Loading

0 comments on commit f42dbe7

Please sign in to comment.