Skip to content

Commit 1c2be66

Browse files
authored
Merge pull request #4065 from element-hq/feature/bma/recoveryKeyUi
Update recovery key UI
2 parents 0648cf3 + ad2496c commit 1c2be66

File tree

37 files changed

+127
-103
lines changed

37 files changed

+127
-103
lines changed

features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package io.element.android.features.securebackup.impl.setup.views
99

1010
import androidx.compose.foundation.background
1111
import androidx.compose.foundation.layout.Arrangement
12+
import androidx.compose.foundation.layout.Box
1213
import androidx.compose.foundation.layout.Column
1314
import androidx.compose.foundation.layout.Row
1415
import androidx.compose.foundation.layout.fillMaxWidth
@@ -24,8 +25,10 @@ import androidx.compose.ui.Alignment
2425
import androidx.compose.ui.ExperimentalComposeUiApi
2526
import androidx.compose.ui.Modifier
2627
import androidx.compose.ui.autofill.AutofillType
28+
import androidx.compose.ui.draw.alpha
2729
import androidx.compose.ui.draw.clip
2830
import androidx.compose.ui.res.stringResource
31+
import androidx.compose.ui.text.font.FontFamily
2932
import androidx.compose.ui.text.input.ImeAction
3033
import androidx.compose.ui.text.input.KeyboardType
3134
import androidx.compose.ui.text.input.VisualTransformation
@@ -88,42 +91,38 @@ private fun RecoveryKeyStaticContent(
8891
state: RecoveryKeyViewState,
8992
onClick: (() -> Unit)?,
9093
) {
91-
Row(
94+
Box(
9295
modifier = Modifier
93-
.fillMaxWidth()
94-
.clip(RoundedCornerShape(14.dp))
95-
.background(
96-
color = ElementTheme.colors.bgSubtleSecondary,
97-
shape = RoundedCornerShape(14.dp)
98-
)
99-
.clickableIfNotNull(onClick)
100-
.padding(horizontal = 16.dp, vertical = 16.dp),
101-
horizontalArrangement = Arrangement.spacedBy(8.dp)
96+
.fillMaxWidth()
97+
.clip(RoundedCornerShape(10.dp))
98+
.background(
99+
color = ElementTheme.colors.bgSubtleSecondary,
100+
)
101+
.clickableIfNotNull(onClick)
102+
.padding(horizontal = 16.dp, vertical = 11.dp),
103+
contentAlignment = Alignment.Center,
102104
) {
103105
if (state.formattedRecoveryKey != null) {
104-
Text(
105-
text = state.formattedRecoveryKey,
106-
modifier = Modifier.weight(1f),
107-
)
108-
Icon(
109-
imageVector = CompoundIcons.Copy(),
110-
contentDescription = stringResource(id = CommonStrings.action_copy),
111-
tint = ElementTheme.colors.iconSecondary,
106+
RecoveryKeyWithCopy(
107+
recoveryKey = state.formattedRecoveryKey,
108+
alpha = 1f,
112109
)
113110
} else {
111+
// Use an invisible recovery key to ensure that the Box size is correct.
112+
val fakeFormattedRecoveryKey = List(12) { "XXXX" }.joinToString(" ")
113+
RecoveryKeyWithCopy(
114+
recoveryKey = fakeFormattedRecoveryKey,
115+
alpha = 0f,
116+
)
114117
Row(
115118
verticalAlignment = Alignment.CenterVertically,
116-
horizontalArrangement = Arrangement.Center,
117-
modifier = Modifier
118-
.fillMaxWidth()
119-
.padding(vertical = 11.dp)
120119
) {
121120
if (state.inProgress) {
122121
CircularProgressIndicator(
123122
modifier = Modifier
124-
.progressSemantics()
125-
.padding(end = 8.dp)
126-
.size(16.dp),
123+
.progressSemantics()
124+
.padding(end = 8.dp)
125+
.size(16.dp),
127126
color = ElementTheme.colors.textPrimary,
128127
strokeWidth = 1.5.dp,
129128
)
@@ -144,6 +143,31 @@ private fun RecoveryKeyStaticContent(
144143
}
145144
}
146145

146+
@Composable
147+
private fun RecoveryKeyWithCopy(
148+
recoveryKey: String,
149+
alpha: Float,
150+
) {
151+
Row(
152+
modifier = Modifier
153+
.fillMaxWidth()
154+
.alpha(alpha),
155+
horizontalArrangement = Arrangement.spacedBy(8.dp),
156+
) {
157+
Text(
158+
text = recoveryKey,
159+
color = ElementTheme.colors.textSecondary,
160+
style = ElementTheme.typography.fontBodyLgRegular.copy(fontFamily = FontFamily.Monospace),
161+
modifier = Modifier.weight(1f),
162+
)
163+
Icon(
164+
imageVector = CompoundIcons.Copy(),
165+
contentDescription = stringResource(id = CommonStrings.action_copy),
166+
tint = ElementTheme.colors.iconSecondary,
167+
)
168+
}
169+
}
170+
147171
@OptIn(ExperimentalComposeUiApi::class)
148172
@Composable
149173
private fun RecoveryKeyFormContent(
@@ -160,12 +184,12 @@ private fun RecoveryKeyFormContent(
160184
}
161185
TextField(
162186
modifier = Modifier
163-
.fillMaxWidth()
164-
.testTag(TestTags.recoveryKey)
165-
.autofill(
166-
autofillTypes = listOf(AutofillType.Password),
167-
onFill = { onChange(it) },
168-
),
187+
.fillMaxWidth()
188+
.testTag(TestTags.recoveryKey)
189+
.autofill(
190+
autofillTypes = listOf(AutofillType.Password),
191+
onFill = { onChange(it) },
192+
),
169193
minLines = 2,
170194
value = state.formattedRecoveryKey.orEmpty(),
171195
onValueChange = onChange,
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

0 commit comments

Comments
 (0)