diff --git a/app/src/androidTest/kotlin/org/libremail/ui/onboarding/OnboardingFlowTest.kt b/app/src/androidTest/kotlin/org/libremail/ui/onboarding/OnboardingFlowTest.kt
index 121a218..ff116c8 100644
--- a/app/src/androidTest/kotlin/org/libremail/ui/onboarding/OnboardingFlowTest.kt
+++ b/app/src/androidTest/kotlin/org/libremail/ui/onboarding/OnboardingFlowTest.kt
@@ -254,10 +254,11 @@ class OnboardingFlowTest {
waitForText("Yahoo Mail")
composeTestRule.onNodeWithText("Yahoo Mail").performClick()
- // Yahoo's setup screen keeps its app-password link…
+ // Yahoo's setup screen keeps its app-password link (now pointing at Yahoo's step-by-step
+ // instructions article instead of the generic account-security page, issue #155)…
waitForText(string(R.string.app_password_open_page, "Yahoo Mail"))
// …but gains no two-factor help link: unlike Gmail and iCloud, Yahoo gates nothing on it
- // (issue #98, #153).
+ // (issue #98, #153, #155).
composeTestRule.onNodeWithText(string(R.string.app_password_2fa_help)).assertDoesNotExist()
composeTestRule.onNodeWithText(string(R.string.app_password_2fa_help_icloud)).assertDoesNotExist()
}
diff --git a/app/src/main/kotlin/org/libremail/domain/model/MailProvider.kt b/app/src/main/kotlin/org/libremail/domain/model/MailProvider.kt
index 5f93cc2..1bfa541 100644
--- a/app/src/main/kotlin/org/libremail/domain/model/MailProvider.kt
+++ b/app/src/main/kotlin/org/libremail/domain/model/MailProvider.kt
@@ -64,7 +64,12 @@ enum class MailProvider(
YAHOO(
key = "yahoo",
displayName = "Yahoo Mail",
- appPasswordHelpUrl = "https://login.yahoo.com/account/security",
+ // Yahoo's own step-by-step "Generate and manage 3rd-party app passwords" article, not
+ // just the generic account-security sign-in page — that page assumes the user already
+ // knows to look for "Create app password" once there (issue #155). Unlike Gmail/iCloud,
+ // this article never lists two-step verification as a prerequisite for generating an app
+ // password, so there is no twoFactorHelpUrl below.
+ appPasswordHelpUrl = "https://my.help.yahoo.com/kb/mail/generate-app-specific-password-sln15241.html",
imapHost = "imap.mail.yahoo.com",
smtpHost = "smtp.mail.yahoo.com",
// Yahoo documents smtp.mail.yahoo.com:465 with implicit SSL/TLS as its outgoing server.
diff --git a/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt b/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt
index 4f30d49..f97dae1 100644
--- a/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt
+++ b/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt
@@ -190,6 +190,13 @@ private fun FormattingToolbar(
underline = true,
onClick = { onToggleStyle(RichStyle.Underline) },
)
+ FormatButton(
+ label = "S",
+ description = stringResource(R.string.format_strikethrough),
+ active = RichTextEditing.isStyled(content, start, end, RichStyle.Strikethrough),
+ strikethrough = true,
+ onClick = { onToggleStyle(RichStyle.Strikethrough) },
+ )
FormatButton(
label = "•",
description = stringResource(R.string.format_bullet_list),
@@ -226,6 +233,7 @@ private fun FormatButton(
fontWeight: FontWeight? = null,
fontStyle: FontStyle? = null,
underline: Boolean = false,
+ strikethrough: Boolean = false,
) {
val colors = MaterialTheme.colorScheme
val background = if (active) colors.secondaryContainer else Color.Transparent
@@ -244,7 +252,11 @@ private fun FormatButton(
style = LocalTextStyle.current.copy(
fontWeight = fontWeight,
fontStyle = fontStyle,
- textDecoration = if (underline) TextDecoration.Underline else null,
+ textDecoration = when {
+ underline -> TextDecoration.Underline
+ strikethrough -> TextDecoration.LineThrough
+ else -> null
+ },
),
)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0aec5ae..a8b8cb7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -97,6 +97,7 @@
Bold
Italic
Underline
+ Strikethrough
Bulleted list
Numbered list
Block quote
diff --git a/app/src/test/kotlin/org/libremail/domain/model/MailProviderTest.kt b/app/src/test/kotlin/org/libremail/domain/model/MailProviderTest.kt
index 69d16de..49f0ea1 100644
--- a/app/src/test/kotlin/org/libremail/domain/model/MailProviderTest.kt
+++ b/app/src/test/kotlin/org/libremail/domain/model/MailProviderTest.kt
@@ -96,7 +96,9 @@ class MailProviderTest {
// generic Apple ID sign-in page (issue #153).
assertEquals("https://support.apple.com/en-us/102660", MailProvider.ICLOUD.twoFactorHelpUrl)
- // Yahoo gates nothing on two-factor, so it must not grow the extra link.
+ // Yahoo gates nothing on two-factor — reconfirmed directly against Yahoo's own help docs,
+ // which never list two-step verification as a prerequisite for generating an app password
+ // (issue #155) — so it must not grow the extra link.
assertNull(MailProvider.YAHOO.twoFactorHelpUrl)
}
@@ -105,6 +107,14 @@ class MailProviderTest {
assertEquals("https://support.apple.com/en-us/102654", MailProvider.ICLOUD.appPasswordHelpUrl)
}
+ @Test
+ fun `yahoo app-password help points at Yahoo's step-by-step instructions, not the generic sign-in page`() {
+ assertEquals(
+ "https://my.help.yahoo.com/kb/mail/generate-app-specific-password-sln15241.html",
+ MailProvider.YAHOO.appPasswordHelpUrl,
+ )
+ }
+
@Test
fun `createAccount trims the email and derives a stable id and display name`() {
val account = MailProvider.GMAIL.createAccount(" User@Gmail.com ")