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 ")