Skip to content

Commit dfdbeed

Browse files
committed
refactor(message-reader): use CSS providers instead of building css directly on DisplayHtml
The key changes include: - Moving `HtmlSettings.kt` and `HtmlSettingsProvider.kt` to :core:common. - Introducing `CssClassNameProvider`, `GlobalCssStyleProvider`, `PlainTextMessagePreElementCssStyleProvider`, and `SignatureCssStyleProvider` to dynamically generate CSS for message display. - Updating `DisplayHtml`, `HtmlProcessor`, and their factories to use these new providers. - Refactoring dependency injection to provide the new CSS services. - Using CSS variables for blockquote border colors in `EmailTextToHtml`.
1 parent 1943c5e commit dfdbeed

File tree

38 files changed

+549
-223
lines changed

38 files changed

+549
-223
lines changed

app-common/src/main/kotlin/net/thunderbird/android/feature/mail/message/reader/api/css/DefaultCssClassNameProvider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class DefaultCssClassNameProvider(
1313
override val mainContentClassName: String = "${defaultNamespaceClassName}__main-content"
1414
override val plainTextMessagePreClassName: String =
1515
if (featureFlagProvider.provide(MessageReaderFeatureFlags.UseNewMessageReaderCssStyles).isEnabled()) {
16-
EmailTextToHtml.K9MAIL_CSS_CLASS
17-
} else {
1816
"${defaultNamespaceClassName}__plain-text-message-pre"
17+
} else {
18+
EmailTextToHtml.K9MAIL_CSS_CLASS
1919
}
2020
override val signatureClassName: String =
2121
if (featureFlagProvider.provide(MessageReaderFeatureFlags.UseNewMessageReaderCssStyles).isEnabled()) {

app-k9mail/src/test/kotlin/app/k9mail/DependencyInjectionTest.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ import com.fsck.k9.job.MailSyncWorker
1515
import com.fsck.k9.job.SyncDebugWorker
1616
import com.fsck.k9.mailstore.AttachmentResolver
1717
import com.fsck.k9.message.html.DisplayHtml
18-
import com.fsck.k9.message.html.HtmlSettings
18+
import com.fsck.k9.message.html.DisplayHtmlFactory
1919
import com.fsck.k9.ui.changelog.ChangeLogMode
2020
import com.fsck.k9.ui.changelog.ChangelogViewModel
21+
import com.fsck.k9.ui.helper.DisplayHtmlUiFactory
2122
import com.fsck.k9.view.K9WebViewClient
2223
import com.fsck.k9.view.MessageWebView
2324
import net.openid.appauth.AppAuthConfiguration
25+
import net.thunderbird.core.common.mail.html.HtmlSettings
2426
import net.thunderbird.core.preference.storage.Storage
2527
import net.thunderbird.feature.account.AccountId
2628
import net.thunderbird.feature.mail.message.list.ui.dialog.SetupArchiveFolderDialogContract
29+
import net.thunderbird.feature.mail.message.reader.api.css.CssClassNameProvider
2730
import org.junit.Test
2831
import org.koin.core.annotation.KoinExperimentalAPI
2932
import org.koin.test.verify.definition
@@ -53,7 +56,13 @@ class DependencyInjectionTest {
5356
injections = injectedParameters(
5457
definition<AccountRemoverWorker>(WorkerParameters::class),
5558
definition<ChangelogViewModel>(ChangeLogMode::class),
56-
definition<DisplayHtml>(HtmlSettings::class),
59+
definition<DisplayHtml>(
60+
HtmlSettings::class,
61+
CssClassNameProvider::class,
62+
List::class,
63+
),
64+
definition<DisplayHtmlFactory>(List::class),
65+
definition<DisplayHtmlUiFactory>(List::class),
5766
definition<K9WebViewClient>(AttachmentResolver::class, MessageWebView.OnPageFinishedListener::class),
5867
definition<MailSyncWorker>(WorkerParameters::class),
5968
definition<SyncDebugWorker>(WorkerParameters::class),

app-thunderbird/src/test/kotlin/net/thunderbird/android/DependencyInjectionTest.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ import com.fsck.k9.job.MailSyncWorker
1515
import com.fsck.k9.job.SyncDebugWorker
1616
import com.fsck.k9.mailstore.AttachmentResolver
1717
import com.fsck.k9.message.html.DisplayHtml
18-
import com.fsck.k9.message.html.HtmlSettings
18+
import com.fsck.k9.message.html.DisplayHtmlFactory
1919
import com.fsck.k9.ui.changelog.ChangeLogMode
2020
import com.fsck.k9.ui.changelog.ChangelogViewModel
21+
import com.fsck.k9.ui.helper.DisplayHtmlUiFactory
2122
import com.fsck.k9.view.K9WebViewClient
2223
import com.fsck.k9.view.MessageWebView
2324
import net.openid.appauth.AppAuthConfiguration
25+
import net.thunderbird.core.common.mail.html.HtmlSettings
2426
import net.thunderbird.core.preference.storage.Storage
2527
import net.thunderbird.feature.account.AccountId
2628
import net.thunderbird.feature.mail.message.list.ui.dialog.SetupArchiveFolderDialogContract
29+
import net.thunderbird.feature.mail.message.reader.api.css.CssClassNameProvider
2730
import org.junit.Test
2831
import org.koin.core.annotation.KoinExperimentalAPI
2932
import org.koin.test.verify.definition
@@ -53,7 +56,13 @@ class DependencyInjectionTest {
5356
injections = injectedParameters(
5457
definition<AccountRemoverWorker>(WorkerParameters::class),
5558
definition<ChangelogViewModel>(ChangeLogMode::class),
56-
definition<DisplayHtml>(HtmlSettings::class),
59+
definition<DisplayHtml>(
60+
HtmlSettings::class,
61+
CssClassNameProvider::class,
62+
List::class,
63+
),
64+
definition<DisplayHtmlFactory>(List::class),
65+
definition<DisplayHtmlUiFactory>(List::class),
5766
definition<K9WebViewClient>(AttachmentResolver::class, MessageWebView.OnPageFinishedListener::class),
5867
definition<MailSyncWorker>(WorkerParameters::class),
5968
definition<SyncDebugWorker>(WorkerParameters::class),

cli/html-cleaner-cli/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ application {
99
}
1010

1111
dependencies {
12+
implementation(projects.core.featureflag)
13+
implementation(projects.feature.mail.message.reader.api)
1214
implementation(projects.library.htmlCleaner)
1315

1416
implementation(libs.clikt)

cli/html-cleaner-cli/src/main/kotlin/app/k9mail/cli/html/cleaner/Main.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ import com.github.ajalt.clikt.core.CliktCommand
66
import com.github.ajalt.clikt.core.Context
77
import com.github.ajalt.clikt.core.main
88
import com.github.ajalt.clikt.parameters.arguments.argument
9+
import com.github.ajalt.clikt.parameters.arguments.default
910
import com.github.ajalt.clikt.parameters.arguments.optional
11+
import com.github.ajalt.clikt.parameters.types.enum
1012
import com.github.ajalt.clikt.parameters.types.file
1113
import com.github.ajalt.clikt.parameters.types.inputStream
1214
import java.io.File
15+
import net.thunderbird.core.featureflag.FeatureFlagResult
16+
import net.thunderbird.feature.mail.message.reader.api.css.CssClassNameProvider
1317
import okio.buffer
1418
import okio.sink
1519
import okio.source
@@ -19,6 +23,10 @@ class HtmlCleaner : CliktCommand() {
1923
val input by argument(help = "HTML input file (needs to be UTF-8 encoded)")
2024
.inputStream()
2125

26+
val app by argument(help = "The app the email will be target to")
27+
.enum<App>(ignoreCase = true)
28+
.default(App.THUNDERBIRD)
29+
2230
val output by argument(help = "Output file")
2331
.file(mustExist = false, canBeDir = false)
2432
.optional()
@@ -38,7 +46,21 @@ class HtmlCleaner : CliktCommand() {
3846

3947
private fun cleanHtml(html: String): String {
4048
val htmlProcessor = HtmlProcessor(
41-
object : HtmlHeadProvider {
49+
featureFlagProvider = { FeatureFlagResult.Enabled },
50+
cssClassNameProvider = object : CssClassNameProvider {
51+
override val defaultNamespaceClassName: String
52+
get() = if (app == App.THUNDERBIRD) {
53+
"net_thunderbird_android"
54+
} else {
55+
"com_fsck_k9"
56+
}
57+
override val rootClassName: String = "${defaultNamespaceClassName}__message-viewer"
58+
override val mainContentClassName: String = "${defaultNamespaceClassName}__main-content"
59+
override val plainTextMessagePreClassName: String =
60+
"${defaultNamespaceClassName}__plain-text-message-pre"
61+
override val signatureClassName: String = "${defaultNamespaceClassName}__signature"
62+
},
63+
htmlHeadProvider = object : HtmlHeadProvider {
4264
override val headHtml = """<meta name="viewport" content="width=device-width"/>"""
4365
},
4466
)
@@ -57,4 +79,6 @@ class HtmlCleaner : CliktCommand() {
5779
}
5880
}
5981

82+
enum class App { THUNDERBIRD, K9MAIL }
83+
6084
fun main(args: Array<String>) = HtmlCleaner().main(args)

core/common/src/commonMain/kotlin/net/thunderbird/core/common/inject/KoinMultibindingCollection.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ inline fun <reified T> Module.singleListOf(vararg items: Definition<T>, qualifie
2929
}
3030
}
3131

32+
/**
33+
* Defines a factory for a list of elements of type [T].
34+
*
35+
* This function creates a factory definition for a list of elements. Each time this list is
36+
* requested, a new list is created, and each element in the list is resolved anew from the
37+
* provided [items] definitions.
38+
*
39+
* @param T The type of elements in the list.
40+
* @param items Vararg of [Definition]s that will be resolved and added to the list.
41+
* @param qualifier Optional [Qualifier] to distinguish this list from others of the same type.
42+
* If null, a default qualifier based on the type [T] will be used.
43+
*/
44+
@KoinDslMarker
45+
inline fun <reified T> Module.factoryListOf(vararg items: Definition<T>, qualifier: Qualifier? = null) {
46+
factory(qualifier ?: defaultListQualifier<T>()) {
47+
items.map { definition -> definition(this, parametersOf()) }
48+
}
49+
}
50+
3251
/**
3352
* Resolves a [List] of instances of type [T].
3453
* This is a helper function for Koin's multibinding feature.

legacy/core/src/main/java/com/fsck/k9/message/html/HtmlSettings.kt renamed to core/common/src/commonMain/kotlin/net/thunderbird/core/common/mail/html/HtmlSettings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fsck.k9.message.html
1+
package net.thunderbird.core.common.mail.html
22

33
data class HtmlSettings(
44
val useDarkMode: Boolean,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.thunderbird.core.common.mail.html
2+
3+
fun interface HtmlSettingsProvider {
4+
fun create(): HtmlSettings
5+
}

feature/mail/message/composer/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ android {
88
}
99

1010
dependencies {
11+
implementation(projects.core.common)
1112
implementation(projects.core.ui.compose.designsystem)
1213
implementation(projects.core.ui.theme.api)
1314
implementation(projects.feature.notification.api)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.thunderbird.feature.mail.message.composer.html
2+
3+
import net.thunderbird.core.common.mail.html.HtmlSettings
4+
import net.thunderbird.core.common.mail.html.HtmlSettingsProvider
5+
import net.thunderbird.core.ui.theme.api.Theme
6+
import net.thunderbird.core.ui.theme.api.ThemeManager
7+
8+
interface MessageComposerHtmlSettingsProvider : HtmlSettingsProvider
9+
10+
internal fun MessageComposerHtmlSettingsProvider(themeManager: ThemeManager): MessageComposerHtmlSettingsProvider =
11+
object : MessageComposerHtmlSettingsProvider {
12+
override fun create(): HtmlSettings = HtmlSettings(
13+
useDarkMode = themeManager.messageComposeTheme == Theme.DARK,
14+
useFixedWidthFont = false,
15+
)
16+
}

0 commit comments

Comments
 (0)