Skip to content

Commit 1148e48

Browse files
PM-14333 Complete fix for crash caused by spannable text creation (#4479)
1 parent f32eecc commit 1148e48

File tree

15 files changed

+384
-545
lines changed

15 files changed

+384
-545
lines changed

app/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ tasks {
367367
maxHeapSize = "2g"
368368
maxParallelForks = Runtime.getRuntime().availableProcessors()
369369
jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC"
370+
android.sourceSets["main"].res.srcDirs("src/test/res")
370371
}
371372
}
372373

app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/checkemail/CheckEmailScreen.kt

+14-42
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,9 @@ import androidx.hilt.navigation.compose.hiltViewModel
3535
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3636
import com.x8bit.bitwarden.R
3737
import com.x8bit.bitwarden.ui.auth.feature.checkemail.handlers.rememberCheckEmailHandler
38-
import com.x8bit.bitwarden.ui.platform.base.util.ClickableTextHighlight
3938
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
40-
import com.x8bit.bitwarden.ui.platform.base.util.createAnnotatedString
41-
import com.x8bit.bitwarden.ui.platform.base.util.createClickableAnnotatedString
4239
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
40+
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
4341
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
4442
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
4543
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTextButton
@@ -152,18 +150,13 @@ private fun CheckEmailContent(
152150
)
153151
Spacer(modifier = Modifier.height(8.dp))
154152

155-
val descriptionAnnotatedString = createAnnotatedString(
156-
mainString = stringResource(
157-
id = R.string.we_sent_an_email_to,
158-
email,
159-
),
160-
highlights = listOf(email),
161-
highlightStyle = SpanStyle(
153+
val descriptionAnnotatedString = R.string.we_sent_an_email_to.toAnnotatedString(
154+
args = arrayOf(email),
155+
emphasisHighlightStyle = SpanStyle(
162156
color = BitwardenTheme.colorScheme.text.primary,
163157
fontSize = BitwardenTheme.typography.bodyMedium.fontSize,
164158
fontWeight = FontWeight.Bold,
165159
),
166-
tag = "EMAIL",
167160
)
168161
Text(
169162
text = descriptionAnnotatedString,
@@ -241,18 +234,14 @@ private fun CheckEmailLegacyContent(
241234
Spacer(modifier = Modifier.height(16.dp))
242235

243236
@Suppress("MaxLineLength")
244-
val descriptionAnnotatedString = createAnnotatedString(
245-
mainString = stringResource(
246-
id = R.string.follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account,
237+
val descriptionAnnotatedString =
238+
R.string.follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account.toAnnotatedString(
247239
email,
248-
),
249-
highlights = listOf(email),
250-
highlightStyle = SpanStyle(
240+
emphasisHighlightStyle = SpanStyle(
251241
color = BitwardenTheme.colorScheme.text.primary,
252242
fontSize = BitwardenTheme.typography.bodyMedium.fontSize,
253243
fontWeight = FontWeight.Bold,
254244
),
255-
tag = "EMAIL",
256245
)
257246
Text(
258247
text = descriptionAnnotatedString,
@@ -276,34 +265,17 @@ private fun CheckEmailLegacyContent(
276265
modifier = Modifier.fillMaxSize(),
277266
horizontalAlignment = Alignment.CenterHorizontally,
278267
) {
279-
val goBackAnnotatedString = createClickableAnnotatedString(
280-
mainString = stringResource(
281-
id = R.string.no_email_go_back_to_edit_your_email_address,
282-
),
283-
highlights = listOf(
284-
ClickableTextHighlight(
285-
textToHighlight = stringResource(id = R.string.go_back),
286-
onTextClick = onChangeEmailClick,
287-
),
288-
),
289-
)
290268
Text(
291-
text = goBackAnnotatedString,
269+
text = R.string.no_email_go_back_to_edit_your_email_address.toAnnotatedString {
270+
onChangeEmailClick()
271+
},
292272
)
293273
Spacer(modifier = Modifier.height(32.dp))
294-
val logInAnnotatedString = createClickableAnnotatedString(
295-
mainString = stringResource(
296-
id = R.string.or_log_in_you_may_already_have_an_account,
297-
),
298-
highlights = listOf(
299-
ClickableTextHighlight(
300-
textToHighlight = stringResource(id = R.string.log_in_verb),
301-
onTextClick = onLoginClick,
302-
),
303-
),
304-
)
305274
Text(
306-
text = logInAnnotatedString,
275+
text = R.string.or_log_in_you_may_already_have_an_account
276+
.toAnnotatedString {
277+
onLoginClick()
278+
},
307279
)
308280
}
309281
}

app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/masterpasswordguidance/MasterPasswordGuidanceScreen.kt

+6-33
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import androidx.compose.ui.unit.dp
2424
import androidx.hilt.navigation.compose.hiltViewModel
2525
import com.x8bit.bitwarden.R
2626
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
27-
import com.x8bit.bitwarden.ui.platform.base.util.bitwardenBoldSpanStyle
28-
import com.x8bit.bitwarden.ui.platform.base.util.createAnnotatedString
2927
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
3028
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
3129
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
@@ -130,6 +128,7 @@ private fun MasterPasswordGuidanceContent(
130128
}
131129
}
132130

131+
@Suppress("MaxLineLength")
133132
@Composable
134133
private fun MasterPasswordGuidanceContentBlocks(modifier: Modifier = Modifier) {
135134
Column(modifier = modifier) {
@@ -138,46 +137,20 @@ private fun MasterPasswordGuidanceContentBlocks(modifier: Modifier = Modifier) {
138137
ContentBlockData(
139138
headerText = stringResource(R.string.choose_three_or_four_random_words)
140139
.toAnnotatedString(),
141-
subtitleText = createAnnotatedString(
142-
mainString = stringResource(
143-
R.string.pick_three_or_four_random_unrelated_words,
144-
),
145-
highlights = listOf(
146-
stringResource(
147-
R.string.pick_three_or_four_random_unrelated_words_highlight,
148-
),
149-
),
150-
highlightStyle = bitwardenBoldSpanStyle,
151-
),
140+
subtitleText = R.string.pick_three_or_four_random_unrelated_words.toAnnotatedString(),
152141
iconVectorResource = R.drawable.ic_number1,
153142
),
154143
ContentBlockData(
155144
headerText = stringResource(R.string.combine_those_words_together)
156145
.toAnnotatedString(),
157-
subtitleText = createAnnotatedString(
158-
mainString = stringResource(
159-
R.string.put_the_words_together_in_any_order_to_form_your_passphrase,
160-
),
161-
highlights = listOf(
162-
stringResource(
163-
R.string.use_hyphens_spaces_or_leave_them_as_long_word_highlight,
164-
),
165-
),
166-
highlightStyle = bitwardenBoldSpanStyle,
167-
),
146+
subtitleText = R.string.put_the_words_together_in_any_order_to_form_your_passphrase
147+
.toAnnotatedString(),
168148
iconVectorResource = R.drawable.ic_number2,
169149
),
170150
ContentBlockData(
171151
headerText = stringResource(R.string.make_it_yours).toAnnotatedString(),
172-
subtitleText = createAnnotatedString(
173-
mainString = stringResource(
174-
R.string.add_a_number_or_symbol_to_make_it_even_stronger,
175-
),
176-
highlights = listOf(
177-
stringResource(R.string.add_a_number_or_symbol_highlight),
178-
),
179-
highlightStyle = bitwardenBoldSpanStyle,
180-
),
152+
subtitleText = R.string.add_a_number_or_symbol_to_make_it_even_stronger
153+
.toAnnotatedString(),
181154
iconVectorResource = R.drawable.ic_number3,
182155
),
183156
),

app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/newdevicenotice/NewDeviceNoticeEmailAccessScreen.kt

+5-9
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import com.x8bit.bitwarden.ui.auth.feature.newdevicenotice.NewDeviceNoticeEmailA
3131
import com.x8bit.bitwarden.ui.auth.feature.newdevicenotice.NewDeviceNoticeEmailAccessAction.EmailAccessToggle
3232
import com.x8bit.bitwarden.ui.auth.feature.newdevicenotice.NewDeviceNoticeEmailAccessEvent.NavigateToTwoFactorOptions
3333
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
34-
import com.x8bit.bitwarden.ui.platform.base.util.createAnnotatedString
3534
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
35+
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
3636
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
3737
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
3838
import com.x8bit.bitwarden.ui.platform.components.toggle.BitwardenSwitch
@@ -146,18 +146,14 @@ private fun MainContent(
146146
modifier = modifier,
147147
) {
148148
Text(
149-
text = createAnnotatedString(
150-
mainString = stringResource(
151-
R.string.do_you_have_reliable_access_to_your_email,
152-
email,
153-
),
154-
mainStringStyle = SpanStyle(
149+
text = R.string.do_you_have_reliable_access_to_your_email.toAnnotatedString(
150+
args = arrayOf(email),
151+
style = SpanStyle(
155152
color = BitwardenTheme.colorScheme.text.primary,
156153
fontSize = BitwardenTheme.typography.bodyLarge.fontSize,
157154
fontWeight = FontWeight.Normal,
158155
),
159-
highlights = listOf(email),
160-
highlightStyle = SpanStyle(
156+
emphasisHighlightStyle = SpanStyle(
161157
color = BitwardenTheme.colorScheme.text.primary,
162158
fontSize = BitwardenTheme.typography.bodyLarge.fontSize,
163159
fontWeight = FontWeight.Bold,

app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/startregistration/StartRegistrationScreen.kt

+13-32
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ import com.x8bit.bitwarden.ui.auth.feature.startregistration.StartRegistrationEv
4949
import com.x8bit.bitwarden.ui.auth.feature.startregistration.StartRegistrationEvent.NavigateToTerms
5050
import com.x8bit.bitwarden.ui.auth.feature.startregistration.handlers.StartRegistrationHandler
5151
import com.x8bit.bitwarden.ui.auth.feature.startregistration.handlers.rememberStartRegistrationHandler
52-
import com.x8bit.bitwarden.ui.platform.base.util.ClickableTextHighlight
5352
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
54-
import com.x8bit.bitwarden.ui.platform.base.util.createClickableAnnotatedString
5553
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
54+
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
5655
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
5756
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
5857
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenStandardIconButton
@@ -288,7 +287,7 @@ private fun StartRegistrationContent(
288287
}
289288
}
290289

291-
@Suppress("LongMethod")
290+
@Suppress("LongMethod", "MaxLineLength")
292291
@Composable
293292
private fun TermsAndPrivacyText(
294293
onTermsClick: () -> Unit,
@@ -297,22 +296,13 @@ private fun TermsAndPrivacyText(
297296
) {
298297
val strTerms = stringResource(id = R.string.terms_of_service)
299298
val strPrivacy = stringResource(id = R.string.privacy_policy)
300-
val strTermsAndPrivacy = stringResource(
301-
id = R.string.by_continuing_you_agree_to_the_terms_of_service_and_privacy_policy,
302-
)
303-
val annotatedLinkString: AnnotatedString = createClickableAnnotatedString(
304-
mainString = strTermsAndPrivacy,
305-
highlights = listOf(
306-
ClickableTextHighlight(
307-
textToHighlight = strTerms,
308-
onTextClick = onTermsClick,
309-
),
310-
ClickableTextHighlight(
311-
textToHighlight = strPrivacy,
312-
onTextClick = onPrivacyPolicyClick,
313-
),
314-
),
315-
)
299+
val annotatedLinkString: AnnotatedString =
300+
R.string.by_continuing_you_agree_to_the_terms_of_service_and_privacy_policy.toAnnotatedString {
301+
when (it) {
302+
"termsOfService" -> onTermsClick()
303+
"privacyPolicy" -> onPrivacyPolicyClick()
304+
}
305+
}
316306
Row(
317307
horizontalArrangement = Arrangement.Start,
318308
verticalAlignment = Alignment.CenterVertically,
@@ -356,19 +346,7 @@ private fun ReceiveMarketingEmailsSwitch(
356346
modifier: Modifier = Modifier,
357347
) {
358348
val unsubscribeString = stringResource(id = R.string.unsubscribe)
359-
360349
@Suppress("MaxLineLength")
361-
val annotatedLinkString = createClickableAnnotatedString(
362-
mainString = stringResource(
363-
id = R.string.get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time,
364-
),
365-
highlights = listOf(
366-
ClickableTextHighlight(
367-
textToHighlight = unsubscribeString,
368-
onTextClick = onUnsubscribeClick,
369-
),
370-
),
371-
)
372350
BitwardenSwitch(
373351
modifier = modifier
374352
.semantics(mergeDescendants = true) {
@@ -382,7 +360,10 @@ private fun ReceiveMarketingEmailsSwitch(
382360
),
383361
)
384362
},
385-
label = annotatedLinkString,
363+
label = R.string.get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time
364+
.toAnnotatedString {
365+
onUnsubscribeClick()
366+
},
386367
isChecked = isChecked,
387368
onCheckedChange = onCheckedChange,
388369
contentDescription = "ReceiveMarketingEmailsToggle",

0 commit comments

Comments
 (0)