Iterate on analytics OptIn screen

This commit is contained in:
Benoit Marty
2023-06-16 09:28:21 +02:00
parent a900721c0e
commit 1e73dfbaf8
3 changed files with 125 additions and 167 deletions

View File

@@ -22,25 +22,27 @@ import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.text.style.UnderlineSpan
import androidx.annotation.StringRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
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.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.CheckCircle
import androidx.compose.material.icons.filled.Poll
import androidx.compose.material.icons.rounded.Check
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.BiasAlignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
@@ -54,9 +56,14 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.features.analytics.api.AnalyticsOptInEvents
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.LinkColor
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
@@ -71,114 +78,122 @@ fun AnalyticsOptInView(
) {
LogCompositions(tag = "Analytics", msg = "Root")
val eventSink = state.eventSink
Box(
HeaderFooterPage(
modifier = modifier
.fillMaxSize()
.systemBarsPadding()
.imePadding()
.imePadding(),
header = { AnalyticsOptInHeader(state) },
content = { AnalyticsOptInContent() },
footer = { AnalyticsOptInFooter(eventSink) })
}
@Composable
fun AnalyticsOptInHeader(state: AnalyticsOptInState) {
Column {
IconTitleSubtitleMolecule(
modifier = Modifier.padding(top = 60.dp),
title = stringResource(id = R.string.screen_analytics_prompt_title, state.applicationName),
subTitle = stringResource(id = R.string.screen_analytics_prompt_help_us_improve),
iconImageVector = Icons.Filled.Poll
)
Text(
text = buildAnnotatedStringWithColoredPart(
R.string.screen_analytics_prompt_read_terms,
R.string.screen_analytics_prompt_read_terms_content_link
),
modifier = Modifier
.fillMaxWidth()
.padding(top = 20.dp),
style = ElementTextStyles.Regular.subheadline,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.secondary,
)
}
}
@Composable
fun AnalyticsOptInContent() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = BiasAlignment(
horizontalBias = 0f,
verticalBias = -0.4f
)
) {
Column(
modifier = Modifier.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Column(modifier = Modifier.weight(1f)) {
Image(
painterResource(id = R.drawable.element_logo_stars),
contentDescription = null,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(16.dp)
)
Text(
text = stringResource(id = R.string.screen_analytics_prompt_title, state.applicationName),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
fontSize = 24.sp,
color = MaterialTheme.colorScheme.primary,
)
Text(
text = stringResource(id = R.string.screen_analytics_prompt_help_us_improve, state.applicationName),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
textAlign = TextAlign.Center,
fontSize = 16.sp,
color = MaterialTheme.colorScheme.secondary,
)
AnalyticsOptInContentRow(
text = stringResource(id = R.string.screen_analytics_prompt_data_usage),
idx = 0
)
AnalyticsOptInContentRow(
text = stringResource(id = R.string.screen_analytics_prompt_third_party_sharing),
idx = 1
)
AnalyticsOptInContentRow(
text = stringResource(id = R.string.screen_analytics_prompt_settings),
idx = 2
)
}
}
}
Text(
text = buildAnnotatedStringWithColoredPart(
R.string.screen_analytics_prompt_read_terms,
R.string.screen_analytics_prompt_read_terms_content_link
),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
textAlign = TextAlign.Center,
fontSize = 16.sp,
color = MaterialTheme.colorScheme.secondary,
)
@Composable
fun AnalyticsOptInContentRow(
text: String,
idx: Int,
) {
val radius = 14.dp
val bgShape = when (idx) {
0 -> RoundedCornerShape(topStart = radius, topEnd = radius)
2 -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius)
else -> RoundedCornerShape(0.dp)
}
Row(
modifier = Modifier
.fillMaxWidth()
.background(
color = LocalColors.current.quinary,
shape = bgShape,
)
.padding(vertical = 12.dp, horizontal = 20.dp),
) {
Icon(
modifier = Modifier
.size(20.dp)
.background(color = MaterialTheme.colorScheme.background, shape = CircleShape)
.padding(2.dp),
imageVector = Icons.Rounded.Check,
contentDescription = null,
// TODO Compound, this color is not yet in the theme
tint = Color(0xFF007A61)
)
Text(
modifier = Modifier.padding(start = 16.dp),
text = text,
fontSize = 14.sp,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary,
)
}
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = Icons.Outlined.CheckCircle,
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary)
Text(
text = stringResource(id = R.string.screen_analytics_prompt_data_usage).toAnnotatedString(),
color = MaterialTheme.colorScheme.secondary,
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = Icons.Outlined.CheckCircle,
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary)
Text(
text = stringResource(id = R.string.screen_analytics_prompt_third_party_sharing).toAnnotatedString(),
color = MaterialTheme.colorScheme.secondary,
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = Icons.Outlined.CheckCircle,
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary)
Text(
text = stringResource(id = R.string.screen_analytics_prompt_settings),
color = MaterialTheme.colorScheme.secondary,
)
}
}
Button(
onClick = { eventSink(AnalyticsOptInEvents.EnableAnalytics(true)) },
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = StringR.string.action_enable))
}
Spacer(modifier = Modifier.height(16.dp))
TextButton(
onClick = { eventSink(AnalyticsOptInEvents.EnableAnalytics(false)) },
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = StringR.string.action_not_now))
}
Spacer(Modifier.height(40.dp))
@Composable
fun AnalyticsOptInFooter(eventSink: (AnalyticsOptInEvents) -> Unit) {
ButtonColumnMolecule {
Button(
onClick = { eventSink(AnalyticsOptInEvents.EnableAnalytics(true)) },
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = StringR.string.action_ok))
}
TextButton(
onClick = { eventSink(AnalyticsOptInEvents.EnableAnalytics(false)) },
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = StringR.string.action_not_now))
}
}
}

View File

@@ -1,57 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="120dp"
android:height="94dp"
android:viewportWidth="120"
android:viewportHeight="94">
<path
android:pathData="M60.396,4.958L60.604,4.958A44.521,44.521 0,0 1,105.125 49.479L105.125,49.479A44.521,44.521 0,0 1,60.604 94L60.396,94A44.521,44.521 0,0 1,15.875 49.479L15.875,49.479A44.521,44.521 0,0 1,60.396 4.958z"
android:fillColor="#0DBD8B"/>
<path
android:pathData="M53.228,26.676C53.228,24.958 54.623,23.566 56.344,23.566C67.82,23.566 77.123,32.847 77.123,44.296C77.123,46.014 75.727,47.406 74.006,47.406C72.285,47.406 70.889,46.014 70.889,44.296C70.889,36.282 64.377,29.785 56.344,29.785C54.623,29.785 53.228,28.393 53.228,26.676Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
<path
android:pathData="M67.772,72.282C67.772,73.999 66.377,75.391 64.655,75.391C53.18,75.391 43.877,66.11 43.877,54.661C43.877,52.944 45.272,51.552 46.994,51.552C48.715,51.552 50.111,52.944 50.111,54.661C50.111,62.675 56.623,69.172 64.655,69.172C66.377,69.172 67.772,70.564 67.772,72.282Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
<path
android:pathData="M37.644,56.734C35.922,56.734 34.527,55.342 34.527,53.625C34.527,42.176 43.83,32.895 55.305,32.895C57.027,32.895 58.422,34.287 58.422,36.004C58.422,37.722 57.027,39.114 55.305,39.114C47.272,39.114 40.76,45.611 40.76,53.625C40.76,55.342 39.365,56.734 37.644,56.734Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
<path
android:pathData="M83.356,42.223C85.078,42.223 86.473,43.615 86.473,45.332C86.473,56.781 77.17,66.063 65.695,66.063C63.973,66.063 62.578,64.671 62.578,62.953C62.578,61.236 63.973,59.844 65.695,59.844C73.728,59.844 80.24,53.347 80.24,45.332C80.24,43.615 81.635,42.223 83.356,42.223Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
<path
android:pathData="M39.571,77.305C40.181,77.305 40.683,76.856 40.769,76.227C41.7,69.687 42.587,68.79 48.918,68.076C49.56,68.001 50.041,67.478 50.041,66.87C50.041,66.251 49.57,65.75 48.929,65.664C42.63,64.843 41.817,64.043 40.769,57.502C40.662,56.873 40.181,56.435 39.571,56.435C38.972,56.435 38.47,56.873 38.374,57.513C37.454,64.053 36.566,64.95 30.235,65.664C29.594,65.739 29.123,66.251 29.123,66.87C29.123,67.478 29.583,67.99 30.235,68.076C36.534,68.951 37.315,69.697 38.374,76.238C38.491,76.867 38.983,77.305 39.571,77.305Z"
android:strokeWidth="1.5"
android:fillColor="#ffffff"
android:strokeColor="#0DBD8B"/>
<path
android:strokeWidth="1"
android:pathData="M82.194,35.392C82.697,35.392 83.111,35.019 83.182,34.494C83.949,29.044 84.682,28.297 89.905,27.701C90.434,27.639 90.831,27.203 90.831,26.697C90.831,26.181 90.443,25.763 89.913,25.692C84.717,25.007 84.046,24.34 83.182,18.89C83.093,18.365 82.697,18.001 82.194,18.001C81.7,18.001 81.285,18.365 81.205,18.899C80.447,24.349 79.714,25.096 74.491,25.692C73.962,25.754 73.574,26.181 73.574,26.697C73.574,27.203 73.953,27.63 74.491,27.701C79.688,28.43 80.332,29.053 81.205,34.503C81.302,35.028 81.708,35.392 82.194,35.392Z"
android:fillColor="#ffffff"
android:strokeColor="#0DBD8B"/>
<path
android:pathData="M113.846,18.87C114.174,18.87 114.444,18.631 114.49,18.296C114.991,14.807 115.468,14.329 118.873,13.948C119.218,13.908 119.477,13.63 119.477,13.305C119.477,12.975 119.224,12.708 118.879,12.662C115.491,12.224 115.054,11.797 114.49,8.309C114.433,7.973 114.174,7.74 113.846,7.74C113.524,7.74 113.254,7.973 113.202,8.315C112.707,11.803 112.23,12.281 108.825,12.662C108.48,12.702 108.227,12.975 108.227,13.305C108.227,13.63 108.474,13.903 108.825,13.948C112.213,14.415 112.633,14.813 113.202,18.301C113.265,18.637 113.53,18.87 113.846,18.87Z"
android:fillColor="#0DBD8B"/>
<path
android:pathData="M107.169,9.131C107.354,9.131 107.506,8.997 107.531,8.808C107.813,6.846 108.081,6.577 109.997,6.363C110.191,6.34 110.336,6.183 110.336,6.001C110.336,5.815 110.194,5.665 110,5.639C108.094,5.393 107.849,5.153 107.531,3.191C107.499,3.002 107.354,2.871 107.169,2.871C106.988,2.871 106.836,3.002 106.807,3.194C106.529,5.156 106.26,5.425 104.345,5.639C104.151,5.662 104.008,5.815 104.008,6.001C104.008,6.183 104.147,6.337 104.345,6.363C106.25,6.625 106.486,6.849 106.807,8.811C106.842,9 106.991,9.131 107.169,9.131Z"
android:fillColor="#0DBD8B"/>
<path
android:pathData="M108.575,24.435C108.8,24.435 108.986,24.271 109.018,24.04C109.362,21.642 109.69,21.314 112.031,21.052C112.268,21.024 112.446,20.833 112.446,20.61C112.446,20.383 112.272,20.199 112.035,20.167C109.706,19.866 109.405,19.573 109.018,17.175C108.978,16.944 108.8,16.783 108.575,16.783C108.353,16.783 108.167,16.944 108.132,17.179C107.792,19.577 107.464,19.905 105.123,20.167C104.885,20.195 104.711,20.383 104.711,20.61C104.711,20.833 104.881,21.02 105.123,21.052C107.452,21.372 107.74,21.646 108.132,24.044C108.175,24.275 108.357,24.435 108.575,24.435Z"
android:fillColor="#0DBD8B"/>
<path
android:pathData="M6.197,15.392C6.504,15.392 6.758,15.168 6.801,14.853C7.27,11.583 7.718,11.135 10.91,10.778C11.233,10.74 11.476,10.479 11.476,10.175C11.476,9.865 11.239,9.615 10.915,9.572C7.739,9.161 7.329,8.761 6.801,5.491C6.747,5.176 6.504,4.958 6.197,4.958C5.895,4.958 5.642,5.176 5.593,5.496C5.129,8.767 4.682,9.215 1.49,9.572C1.166,9.609 0.929,9.865 0.929,10.175C0.929,10.479 1.161,10.735 1.49,10.778C4.666,11.215 5.059,11.589 5.593,14.859C5.652,15.174 5.9,15.392 6.197,15.392Z"
android:fillColor="#0DBD8B"/>
<path
android:pathData="M13.231,5.653C13.375,5.653 13.493,5.549 13.513,5.402C13.732,3.876 13.941,3.667 15.431,3.5C15.582,3.482 15.695,3.36 15.695,3.218C15.695,3.074 15.584,2.957 15.433,2.937C13.951,2.745 13.76,2.559 13.513,1.033C13.488,0.886 13.375,0.784 13.231,0.784C13.09,0.784 12.972,0.886 12.95,1.035C12.733,2.561 12.524,2.77 11.035,2.937C10.884,2.955 10.773,3.074 10.773,3.218C10.773,3.36 10.881,3.48 11.035,3.5C12.517,3.704 12.7,3.878 12.95,5.404C12.977,5.551 13.093,5.653 13.231,5.653Z"
android:strokeAlpha="0.4"
android:fillColor="#0DBD8B"
android:fillAlpha="0.4"/>
<path
android:pathData="M16.747,11.914C16.89,11.914 17.009,11.809 17.029,11.663C17.248,10.136 17.457,9.927 18.946,9.761C19.097,9.743 19.21,9.621 19.21,9.479C19.21,9.335 19.1,9.218 18.949,9.198C17.467,9.006 17.275,8.819 17.029,7.293C17.004,7.147 16.89,7.044 16.747,7.044C16.606,7.044 16.488,7.147 16.465,7.296C16.249,8.822 16.04,9.031 14.55,9.198C14.399,9.215 14.289,9.335 14.289,9.479C14.289,9.621 14.397,9.741 14.55,9.761C16.032,9.965 16.216,10.139 16.465,11.665C16.493,11.812 16.609,11.914 16.747,11.914Z"
android:strokeAlpha="0.4"
android:fillColor="#0DBD8B"
android:fillAlpha="0.4"/>
</vector>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"We "<b>"don\'t"</b>" record or profile any account data"</string>
<string name="screen_analytics_prompt_help_us_improve">"Help us identify issues and improve %1$s by sharing anonymous usage data."</string>
<string name="screen_analytics_prompt_data_usage">"We won\'t record or profile any personal data"</string>
<string name="screen_analytics_prompt_help_us_improve">"Share anonymous usage data to help us identify issues."</string>
<string name="screen_analytics_prompt_read_terms">"You can read all our terms %1$s."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"here"</string>
<string name="screen_analytics_prompt_settings">"You can turn this off anytime in settings"</string>
<string name="screen_analytics_prompt_third_party_sharing">"We "<b>"don\'t"</b>" share information with third parties"</string>
<string name="screen_analytics_prompt_settings">"You can turn this off anytime"</string>
<string name="screen_analytics_prompt_third_party_sharing">"We won\'t share your data with third parties"</string>
<string name="screen_analytics_prompt_title">"Help improve %1$s"</string>
</resources>