diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettings.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettings.kt index 005038fb0ba..fff6a1119d4 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettings.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettings.kt @@ -1,5 +1,7 @@ package net.thunderbird.core.preference +import net.thunderbird.core.preference.privacy.PrivacySettings + /** * Stores a snapshot of the app's general settings. * @@ -37,6 +39,7 @@ data class GeneralSettings( val quietTimeStarts: String, val isQuietTimeEnabled: Boolean, val isQuietTime: Boolean, + val privacy: PrivacySettings, ) enum class BackgroundSync { diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettingsManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettingsManager.kt index ee36cce3189..c6e3b3450f3 100644 --- a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettingsManager.kt +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/GeneralSettingsManager.kt @@ -1,13 +1,14 @@ package net.thunderbird.core.preference import kotlinx.coroutines.flow.Flow +import net.thunderbird.core.preference.privacy.PrivacySettingsManager /** * Retrieve and modify general settings. * * TODO: Add more settings as needed. */ -interface GeneralSettingsManager { +interface GeneralSettingsManager : PrivacySettingsManager { fun getSettings(): GeneralSettings fun getSettingsFlow(): Flow diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettings.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettings.kt new file mode 100644 index 00000000000..8ad058942a9 --- /dev/null +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettings.kt @@ -0,0 +1,5 @@ +package net.thunderbird.core.preference.privacy + +data class PrivacySettings( + val isHideTimeZone: Boolean, +) diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsManager.kt new file mode 100644 index 00000000000..248acfb7b0b --- /dev/null +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsManager.kt @@ -0,0 +1,7 @@ +package net.thunderbird.core.preference.privacy + +interface PrivacySettingsManager { + val privacySettings: PrivacySettings + + fun setIsHideTimeZone(isHideTimeZone: Boolean) +} diff --git a/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt new file mode 100644 index 00000000000..ba769f3435f --- /dev/null +++ b/core/preference/api/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/PrivacySettingsPreferenceManager.kt @@ -0,0 +1,5 @@ +package net.thunderbird.core.preference.privacy + +import net.thunderbird.core.preference.PreferenceManager + +interface PrivacySettingsPreferenceManager : PreferenceManager diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsManager.kt new file mode 100644 index 00000000000..2d088755001 --- /dev/null +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsManager.kt @@ -0,0 +1,13 @@ +package net.thunderbird.core.preference.privacy + +class DefaultPrivacySettingsManager( + private val preferenceManager: PrivacySettingsPreferenceManager, +) : PrivacySettingsManager { + override val privacySettings: PrivacySettings + get() = preferenceManager.getConfig() + + override fun setIsHideTimeZone(isHideTimeZone: Boolean) { + val privacySettings = preferenceManager.getConfig() + preferenceManager.save(privacySettings.copy(isHideTimeZone = isHideTimeZone)) + } +} diff --git a/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt new file mode 100644 index 00000000000..4f9c5664b8a --- /dev/null +++ b/core/preference/impl/src/commonMain/kotlin/net/thunderbird/core/preference/privacy/DefaultPrivacySettingsPreferenceManager.kt @@ -0,0 +1,82 @@ +package net.thunderbird.core.preference.privacy + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import net.thunderbird.core.preference.PreferenceChangeBroker +import net.thunderbird.core.preference.PreferenceChangeSubscriber +import net.thunderbird.core.preference.storage.Storage +import net.thunderbird.core.preference.storage.StorageEditor + +class DefaultPrivacySettingsPreferenceManager( + private val storage: Storage, + private val storageEditor: StorageEditor, + private val changeBroker: PreferenceChangeBroker, + private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, + private var scope: CoroutineScope = CoroutineScope(SupervisorJob()), +) : PrivacySettingsPreferenceManager { + private val configState: MutableStateFlow = MutableStateFlow(value = loadConfig()) + private val mutex = Mutex() + + init { + asSettingsFlow() + .onEach { config -> + configState.update { config } + } + .launchIn(scope) + } + + override fun save(config: PrivacySettings) { + configState.update { config } + writeConfig(config) + } + + override fun getConfig(): PrivacySettings = configState.value + override fun getConfigFlow(): Flow = configState + + // Not 100% sure if this method is really required, but applied the same logic + // present in the RealDrawerConfigManager implementation + private fun asSettingsFlow(): Flow { + return callbackFlow { + send(loadConfig()) + + val subscriber = PreferenceChangeSubscriber { + configState.update { loadConfig() } + } + + changeBroker.subscribe(subscriber) + + awaitClose { + changeBroker.unsubscribe(subscriber) + } + } + } + + private fun loadConfig(): PrivacySettings = PrivacySettings( + isHideTimeZone = storage.getBoolean(KEY_HIDE_TIME_ZONE, false), + ) + + private fun writeConfig(config: PrivacySettings) { + scope.launch(ioDispatcher) { + mutex.withLock { + storageEditor.putBoolean(KEY_HIDE_TIME_ZONE, config.isHideTimeZone) + storageEditor.commit() + } + } + } + + companion object { + private const val KEY_HIDE_TIME_ZONE = "hideTimeZone" + } +} diff --git a/feature/mail/message/list/src/test/kotlin/net/thunderbird/feature/mail/message/list/domain/usecase/BuildSwipeActionsTest.kt b/feature/mail/message/list/src/test/kotlin/net/thunderbird/feature/mail/message/list/domain/usecase/BuildSwipeActionsTest.kt index 3afc73cae35..1cf0aecb62f 100644 --- a/feature/mail/message/list/src/test/kotlin/net/thunderbird/feature/mail/message/list/domain/usecase/BuildSwipeActionsTest.kt +++ b/feature/mail/message/list/src/test/kotlin/net/thunderbird/feature/mail/message/list/domain/usecase/BuildSwipeActionsTest.kt @@ -5,6 +5,7 @@ import assertk.assertThat import assertk.assertions.containsOnly import assertk.assertions.hasSize import assertk.assertions.isEmpty +import dev.mokkery.mock import kotlin.random.Random import kotlin.test.Test import kotlin.uuid.ExperimentalUuidApi @@ -19,6 +20,8 @@ import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.GeneralSettingsManager import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings +import net.thunderbird.core.preference.privacy.PrivacySettingsManager import net.thunderbird.core.preference.storage.Storage import net.thunderbird.feature.mail.message.list.fakes.FakeAccount import net.thunderbird.feature.mail.message.list.fakes.FakeAccountManager @@ -54,6 +57,8 @@ class BuildSwipeActionsTest { quietTimeEnds = "7:00", isQuietTime = false, isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), + ) @Test @@ -366,7 +371,7 @@ class BuildSwipeActionsTest { accountsUuids: List, storageValues: Map = mapOf(), ): BuildSwipeActions = BuildSwipeActions( - generalSettingsManager = FakeGeneralSettingsManager(initialGeneralSettings), + generalSettingsManager = FakeGeneralSettingsManager(initialGeneralSettings, mock()), accountManager = FakeAccountManager(accounts = accountsUuids.map { FakeAccount(uuid = it) }), storage = FakeStorage(storageValues), ) @@ -374,7 +379,8 @@ class BuildSwipeActionsTest { private class FakeGeneralSettingsManager( initialGeneralSettings: GeneralSettings, -) : GeneralSettingsManager { + private val privacySettingsManager: PrivacySettingsManager, +) : GeneralSettingsManager, PrivacySettingsManager by privacySettingsManager { private val generalSettings = MutableStateFlow(initialGeneralSettings) override fun getSettings(): GeneralSettings = generalSettings.value @@ -447,6 +453,10 @@ private class FakeGeneralSettingsManager( override fun setIsQuietTimeEnabled(isQuietTimeEnabled: Boolean) = error( "not implemented", ) + + override fun setIsHideTimeZone(isHideTimeZone: Boolean) = error( + "not implemented", + ) } private class FakeStorage( diff --git a/legacy/core/src/main/java/com/fsck/k9/K9.kt b/legacy/core/src/main/java/com/fsck/k9/K9.kt index 9a2d9d09679..dc4b24affed 100644 --- a/legacy/core/src/main/java/com/fsck/k9/K9.kt +++ b/legacy/core/src/main/java/com/fsck/k9/K9.kt @@ -200,9 +200,6 @@ object K9 : KoinComponent { @JvmStatic var isHideUserAgent = false - @JvmStatic - var isHideTimeZone = false - @get:Synchronized @set:Synchronized @JvmStatic @@ -300,7 +297,6 @@ object K9 : KoinComponent { messageViewPostMarkAsUnreadNavigation = storage.getEnum("messageViewPostMarkAsUnreadAction", PostMarkAsUnreadNavigation.ReturnToMessageList) isHideUserAgent = storage.getBoolean("hideUserAgent", false) - isHideTimeZone = storage.getBoolean("hideTimeZone", false) isConfirmDelete = storage.getBoolean("confirmDelete", false) isConfirmDiscardMessage = storage.getBoolean("confirmDiscardMessage", true) @@ -374,7 +370,6 @@ object K9 : KoinComponent { editor.putEnum("messageViewPostDeleteAction", messageViewPostRemoveNavigation) editor.putEnum("messageViewPostMarkAsUnreadAction", messageViewPostMarkAsUnreadNavigation) editor.putBoolean("hideUserAgent", isHideUserAgent) - editor.putBoolean("hideTimeZone", isHideTimeZone) editor.putString("language", k9Language) diff --git a/legacy/core/src/main/java/com/fsck/k9/autocrypt/AutocryptTransferMessageCreator.kt b/legacy/core/src/main/java/com/fsck/k9/autocrypt/AutocryptTransferMessageCreator.kt index fccdca46cd6..c007b612185 100644 --- a/legacy/core/src/main/java/com/fsck/k9/autocrypt/AutocryptTransferMessageCreator.kt +++ b/legacy/core/src/main/java/com/fsck/k9/autocrypt/AutocryptTransferMessageCreator.kt @@ -1,6 +1,5 @@ package com.fsck.k9.autocrypt -import com.fsck.k9.K9 import com.fsck.k9.mail.Address import com.fsck.k9.mail.Flag import com.fsck.k9.mail.Message @@ -13,8 +12,12 @@ import com.fsck.k9.mail.internet.MimeMultipart import com.fsck.k9.mail.internet.TextBody import com.fsck.k9.mailstore.BinaryMemoryBody import java.util.Date +import net.thunderbird.core.preference.GeneralSettingsManager -class AutocryptTransferMessageCreator(private val stringProvider: AutocryptStringProvider) { +class AutocryptTransferMessageCreator( + private val stringProvider: AutocryptStringProvider, + private val generalSettingsManager: GeneralSettingsManager, +) { fun createAutocryptTransferMessage(data: ByteArray, address: Address): Message { try { val subjectText = stringProvider.transferMessageSubject() @@ -41,7 +44,10 @@ class AutocryptTransferMessageCreator(private val stringProvider: AutocryptStrin message.subject = subjectText message.setHeader("Autocrypt-Setup-Message", "v1") message.internalDate = nowDate - message.addSentDate(nowDate, K9.isHideTimeZone) + message.addSentDate( + nowDate, + generalSettingsManager.getSettings().privacy.isHideTimeZone, + ) message.setFrom(address) message.setHeader("To", address.toEncodedString()) diff --git a/legacy/core/src/main/java/com/fsck/k9/autocrypt/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/autocrypt/KoinModule.kt index ef114f0081d..0ee31fd2b9c 100644 --- a/legacy/core/src/main/java/com/fsck/k9/autocrypt/KoinModule.kt +++ b/legacy/core/src/main/java/com/fsck/k9/autocrypt/KoinModule.kt @@ -3,6 +3,11 @@ package com.fsck.k9.autocrypt import org.koin.dsl.module val autocryptModule = module { - single { AutocryptTransferMessageCreator(get()) } + single { + AutocryptTransferMessageCreator( + stringProvider = get(), + generalSettingsManager = get(), + ) + } single { AutocryptDraftStateHeaderParser() } } diff --git a/legacy/core/src/main/java/com/fsck/k9/message/quote/HtmlQuoteCreator.java b/legacy/core/src/main/java/com/fsck/k9/message/quote/HtmlQuoteCreator.java index 80769954f50..a460dd07a9f 100644 --- a/legacy/core/src/main/java/com/fsck/k9/message/quote/HtmlQuoteCreator.java +++ b/legacy/core/src/main/java/com/fsck/k9/message/quote/HtmlQuoteCreator.java @@ -12,6 +12,7 @@ import com.fsck.k9.mail.Message; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.message.html.HtmlConverter; +import net.thunderbird.core.preference.GeneralSettingsManager; public class HtmlQuoteCreator { @@ -42,11 +43,11 @@ public class HtmlQuoteCreator { * @return Modified insertable message. */ public static InsertableHtmlContent quoteOriginalHtmlMessage(Message originalMessage, - String messageBody, QuoteStyle quoteStyle) { + String messageBody, QuoteStyle quoteStyle, GeneralSettingsManager generalSettingsManager) { CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class); InsertableHtmlContent insertable = findInsertionPoints(messageBody); - String sentDate = new QuoteDateFormatter().format(originalMessage.getSentDate()); + String sentDate = new QuoteDateFormatter(generalSettingsManager).format(originalMessage.getSentDate()); String fromAddress = Address.toString(originalMessage.getFrom()); if (quoteStyle == QuoteStyle.PREFIX) { StringBuilder header = new StringBuilder(); diff --git a/legacy/core/src/main/java/com/fsck/k9/message/quote/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/message/quote/KoinModule.kt index 19e6d6101e3..4558fbb698a 100644 --- a/legacy/core/src/main/java/com/fsck/k9/message/quote/KoinModule.kt +++ b/legacy/core/src/main/java/com/fsck/k9/message/quote/KoinModule.kt @@ -3,6 +3,6 @@ package com.fsck.k9.message.quote import org.koin.dsl.module val quoteModule = module { - factory { QuoteDateFormatter() } + factory { QuoteDateFormatter(generalSettingsManager = get()) } factory { TextQuoteCreator(get(), get()) } } diff --git a/legacy/core/src/main/java/com/fsck/k9/message/quote/QuoteDateFormatter.kt b/legacy/core/src/main/java/com/fsck/k9/message/quote/QuoteDateFormatter.kt index 608c5cb9414..a0ecbdc2050 100644 --- a/legacy/core/src/main/java/com/fsck/k9/message/quote/QuoteDateFormatter.kt +++ b/legacy/core/src/main/java/com/fsck/k9/message/quote/QuoteDateFormatter.kt @@ -1,14 +1,16 @@ package com.fsck.k9.message.quote -import com.fsck.k9.K9 import java.text.DateFormat import java.util.Date import java.util.TimeZone +import net.thunderbird.core.preference.GeneralSettingsManager /** * Convert a date into a locale-specific date string suitable for use in a header for a quoted message. */ -class QuoteDateFormatter { +class QuoteDateFormatter( + private val generalSettingsManager: GeneralSettingsManager, +) { fun format(date: Date): String { return try { @@ -21,7 +23,7 @@ class QuoteDateFormatter { private fun createDateFormat(): DateFormat { return DateFormat.getDateTimeInstance(DATE_STYLE, TIME_STYLE).apply { - if (K9.isHideTimeZone) { + if (generalSettingsManager.getSettings().privacy.isHideTimeZone) { timeZone = TimeZone.getTimeZone("UTC") } } diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt index a86704aef19..27455af0fe1 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt @@ -5,6 +5,10 @@ import net.thunderbird.core.preference.DefaultPreferenceChangeBroker import net.thunderbird.core.preference.GeneralSettingsManager import net.thunderbird.core.preference.PreferenceChangeBroker import net.thunderbird.core.preference.PreferenceChangePublisher +import net.thunderbird.core.preference.privacy.DefaultPrivacySettingsManager +import net.thunderbird.core.preference.privacy.DefaultPrivacySettingsPreferenceManager +import net.thunderbird.core.preference.privacy.PrivacySettingsManager +import net.thunderbird.core.preference.privacy.PrivacySettingsPreferenceManager import net.thunderbird.feature.mail.account.api.AccountManager import org.koin.core.qualifier.named import org.koin.dsl.bind @@ -26,11 +30,20 @@ val preferencesModule = module { factory { FolderSettingsProvider(folderRepository = get()) } factory { get() } factory> { get() } + single { + DefaultPrivacySettingsPreferenceManager( + storage = get().storage, + storageEditor = get().createStorageEditor(), + changeBroker = get(), + ) + } + single { DefaultPrivacySettingsManager(preferenceManager = get()) } single { RealGeneralSettingsManager( preferences = get(), coroutineScope = get(named("AppCoroutineScope")), changePublisher = get(), + privacySettingsManager = get(), ) } bind GeneralSettingsManager::class single { diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt index 59bb88d7a41..fb75804a665 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt @@ -21,6 +21,7 @@ import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.GeneralSettingsManager import net.thunderbird.core.preference.PreferenceChangePublisher import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettingsManager import net.thunderbird.core.preference.storage.Storage import net.thunderbird.core.preference.storage.StorageEditor import net.thunderbird.core.preference.storage.getEnumOrDefault @@ -47,12 +48,15 @@ internal const val KEY_QUIET_TIME_ENABLED = "quietTimeEnabled" * The [GeneralSettings] instance managed by this class is updated with state from [K9] when [K9.saveSettingsAsync] is * called. */ +// TODO(#9432): Split GeneralSettings and GeneralSettingsManager in smaller classes/interfaces +@Suppress("TooManyFunctions") internal class RealGeneralSettingsManager( private val preferences: Preferences, private val coroutineScope: CoroutineScope, private val changePublisher: PreferenceChangePublisher, private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO, -) : GeneralSettingsManager { + private val privacySettingsManager: PrivacySettingsManager, +) : GeneralSettingsManager, PrivacySettingsManager by privacySettingsManager { private val settingsFlow = MutableSharedFlow(replay = 1) private var generalSettings: GeneralSettings? = null val clock = DI.get() @@ -229,6 +233,13 @@ internal class RealGeneralSettingsManager( getSettings().copy(isQuietTimeEnabled = isQuietTimeEnabled).persist() } + override fun setIsHideTimeZone(isHideTimeZone: Boolean) { + privacySettingsManager.setIsHideTimeZone(isHideTimeZone) + getSettings() + .copy(privacy = privacySettings) + .persist() + } + private fun writeSettings(editor: StorageEditor, settings: GeneralSettings) { editor.putBoolean("showRecentChanges", settings.showRecentChanges) editor.putEnum("theme", settings.appTheme) @@ -295,6 +306,7 @@ internal class RealGeneralSettingsManager( quietTimeStarts = storage.getStringOrDefault(KEY_QUIET_TIME_STARTS, "21:00"), isQuietTimeEnabled = storage.getBoolean(KEY_QUIET_TIME_ENABLED, false), isQuietTime = getIsQuietTime(), + privacy = privacySettingsManager.privacySettings, ) updateSettingsFlow(settings) diff --git a/legacy/core/src/test/java/com/fsck/k9/helper/MessageHelperTest.kt b/legacy/core/src/test/java/com/fsck/k9/helper/MessageHelperTest.kt index 3cbf2f5235d..f9160543fdf 100644 --- a/legacy/core/src/test/java/com/fsck/k9/helper/MessageHelperTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/helper/MessageHelperTest.kt @@ -19,6 +19,7 @@ import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.GeneralSettingsManager import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.Before import org.junit.Test import org.mockito.kotlin.doReturn @@ -64,6 +65,7 @@ class MessageHelperTest : RobolectricTest() { isQuietTimeEnabled = false, quietTimeEnds = "7:00", quietTimeStarts = "7:00", + privacy = PrivacySettings(isHideTimeZone = false), ), ) } diff --git a/legacy/core/src/test/java/com/fsck/k9/message/quote/QuoteDateFormatterTest.kt b/legacy/core/src/test/java/com/fsck/k9/message/quote/QuoteDateFormatterTest.kt index db69e8ea757..27a626eabba 100644 --- a/legacy/core/src/test/java/com/fsck/k9/message/quote/QuoteDateFormatterTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/message/quote/QuoteDateFormatterTest.kt @@ -2,25 +2,67 @@ package com.fsck.k9.message.quote import assertk.assertThat import assertk.assertions.isEqualTo -import com.fsck.k9.K9 import java.time.ZonedDateTime import java.util.Date import java.util.Locale import java.util.TimeZone +import net.thunderbird.core.preference.AppTheme +import net.thunderbird.core.preference.BackgroundSync +import net.thunderbird.core.preference.GeneralSettings +import net.thunderbird.core.preference.GeneralSettingsManager +import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.After import org.junit.Before import org.junit.Test +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever class QuoteDateFormatterTest { private lateinit var originalLocale: Locale private var originalTimeZone: TimeZone? = null - private val quoteDateFormatter = QuoteDateFormatter() + private val generalSettingsManager: GeneralSettingsManager = mock() + private val fakeGeneralSettings = GeneralSettings( + backgroundSync = BackgroundSync.NEVER, + showRecentChanges = false, + appTheme = AppTheme.FOLLOW_SYSTEM, + messageViewTheme = SubTheme.USE_GLOBAL, + messageComposeTheme = SubTheme.USE_GLOBAL, + fixedMessageViewTheme = false, + privacy = PrivacySettings(isHideTimeZone = false), + isAutoFitWidth = false, + isThreadedViewEnabled = false, + isUseMessageViewFixedWidthFont = false, + isShowContactPicture = false, + isMessageListSenderAboveSubject = false, + isChangeContactNameColor = false, + isColorizeMissingContactPictures = false, + shouldShowSetupArchiveFolderDialog = false, + isShowContactName = false, + isShowUnifiedInbox = false, + isShowStarredCount = false, + isShowComposeButtonOnMessageList = false, + isUseBackgroundAsUnreadIndicator = false, + isShowCorrespondentNames = false, + isShowAnimations = false, + isShowMessageListStars = false, + isQuietTime = false, + isQuietTimeEnabled = false, + quietTimeStarts = "7:00", + quietTimeEnds = "7:00", + + ) + private val quoteDateFormatter = QuoteDateFormatter( + generalSettingsManager = generalSettingsManager, + ) @Before fun setUp() { originalLocale = Locale.getDefault() originalTimeZone = TimeZone.getDefault() TimeZone.setDefault(TimeZone.getTimeZone("GMT+02:00")) + whenever(generalSettingsManager.getSettings()) doReturn fakeGeneralSettings } @After @@ -31,7 +73,8 @@ class QuoteDateFormatterTest { @Test fun hideTimeZoneEnabled_UsLocale() { - K9.isHideTimeZone = true + whenever(generalSettingsManager.getSettings()) doReturn + fakeGeneralSettings.copy(privacy = fakeGeneralSettings.privacy.copy(isHideTimeZone = true)) Locale.setDefault(Locale.US) val formattedDate = quoteDateFormatter.format("2020-09-19T20:00:00+00:00".toDate()) @@ -41,7 +84,8 @@ class QuoteDateFormatterTest { @Test fun hideTimeZoneEnabled_GermanyLocale() { - K9.isHideTimeZone = true + whenever(generalSettingsManager.getSettings()) doReturn + fakeGeneralSettings.copy(privacy = fakeGeneralSettings.privacy.copy(isHideTimeZone = true)) Locale.setDefault(Locale.GERMANY) val formattedDate = quoteDateFormatter.format("2020-09-19T20:00:00+00:00".toDate()) @@ -51,7 +95,6 @@ class QuoteDateFormatterTest { @Test fun hideTimeZoneDisabled_UsLocale() { - K9.isHideTimeZone = false Locale.setDefault(Locale.US) val formattedDate = quoteDateFormatter.format("2020-09-19T20:00:00+00:00".toDate()) @@ -61,7 +104,6 @@ class QuoteDateFormatterTest { @Test fun hideTimeZoneDisabled_GermanyLocale() { - K9.isHideTimeZone = false Locale.setDefault(Locale.GERMANY) val formattedDate = quoteDateFormatter.format("2020-09-19T20:00:00+00:00".toDate()) diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt index 133e875b163..b593cd00fbf 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt @@ -12,6 +12,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.Test import org.mockito.Mockito.verify import org.mockito.kotlin.any @@ -148,6 +149,7 @@ class AuthenticationErrorNotificationControllerTest : RobolectricTest() { quietTimeStarts = "7:00", quietTimeEnds = "7:00", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) }, ) { diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt index 1b51516da0c..282f3b48966 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt @@ -12,6 +12,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.Test import org.mockito.Mockito.verify import org.mockito.kotlin.any @@ -148,6 +149,7 @@ class CertificateErrorNotificationControllerTest : RobolectricTest() { quietTimeStarts = "7:00", quietTimeEnds = "7:00", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) }, ) { diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt index 26dd477343d..536c4851e2d 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt @@ -24,6 +24,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import net.thunderbird.core.testing.TestClock import org.junit.Test import org.mockito.kotlin.doAnswer @@ -78,6 +79,7 @@ class NewMailNotificationManagerTest { quietTimeStarts = "7:00", quietTimeEnds = "7:00", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) }, ), diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt index c18a2d910f2..188ee045aaa 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt @@ -14,6 +14,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.Test import org.mockito.kotlin.any import org.mockito.kotlin.doReturn @@ -174,6 +175,7 @@ class NotificationContentCreatorTest : RobolectricTest() { quietTimeStarts = "7:00", quietTimeEnds = "7:00", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) }, ) diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt index 320d64cb986..0cc1cd394e2 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt @@ -12,6 +12,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import org.junit.Test import org.mockito.ArgumentMatchers.anyLong import org.mockito.Mockito.verify @@ -65,6 +66,7 @@ class SendFailedNotificationControllerTest : RobolectricTest() { quietTimeStarts = "7:00", quietTimeEnds = "7:00", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) }, ) diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt index ab7748a5686..915fbc2e23b 100644 --- a/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt @@ -15,6 +15,7 @@ import net.thunderbird.core.preference.AppTheme import net.thunderbird.core.preference.BackgroundSync import net.thunderbird.core.preference.GeneralSettings import net.thunderbird.core.preference.SubTheme +import net.thunderbird.core.preference.privacy.PrivacySettings import net.thunderbird.core.testing.TestClock import org.junit.After import org.junit.Before @@ -57,6 +58,7 @@ class SummaryNotificationDataCreatorTest { quietTimeStarts = "0:00", quietTimeEnds = "23:59", isQuietTimeEnabled = false, + privacy = PrivacySettings(isHideTimeZone = false), ) private val notificationDataCreator = SummaryNotificationDataCreator( singleMessageNotificationDataCreator = SingleMessageNotificationDataCreator(), diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java b/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java index d6fbc7b7e63..e1b2977b75d 100644 --- a/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java +++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java @@ -118,6 +118,7 @@ import com.google.android.material.textview.MaterialTextView; import net.thunderbird.core.android.account.MessageFormat; import net.thunderbird.core.android.contact.ContactIntentHelper; +import net.thunderbird.core.preference.GeneralSettingsManager; import net.thunderbird.core.ui.theme.manager.ThemeManager; import net.thunderbird.feature.search.LocalMessageSearch; import org.openintents.openpgp.OpenPgpApiManager; @@ -191,6 +192,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, private final DefaultFolderProvider defaultFolderProvider = DI.get(DefaultFolderProvider.class); private final MessagingController messagingController = DI.get(MessagingController.class); private final Preferences preferences = DI.get(Preferences.class); + private final GeneralSettingsManager generalSettingsManager = DI.get(GeneralSettingsManager.class); private final IntentDataMapper indentDataMapper = DI.get(IntentDataMapper.class); @@ -643,7 +645,7 @@ private MessageBuilder createMessageBuilder(boolean isDraft) { builder.setSubject(Utility.stripNewLines(subjectView.getText().toString())) .setSentDate(new Date()) - .setHideTimeZone(K9.isHideTimeZone()) + .setHideTimeZone(generalSettingsManager.getPrivacySettings().isHideTimeZone()) .setInReplyTo(repliedToMessageId) .setReferences(referencedMessageIds) .setRequestReadReceipt(requestReadReceipt) diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/compose/QuotedMessagePresenter.java b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/compose/QuotedMessagePresenter.java index 51145cd491c..d253b177807 100644 --- a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/compose/QuotedMessagePresenter.java +++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/compose/QuotedMessagePresenter.java @@ -31,6 +31,7 @@ import com.fsck.k9.message.signature.TextSignatureRemover; import net.thunderbird.core.android.account.QuoteStyle; import net.thunderbird.core.logging.legacy.Log; +import net.thunderbird.core.preference.GeneralSettingsManager; public class QuotedMessagePresenter { @@ -42,6 +43,7 @@ public class QuotedMessagePresenter { private static final int UNKNOWN_LENGTH = 0; private final TextQuoteCreator textQuoteCreator = DI.get(TextQuoteCreator.class); + private final GeneralSettingsManager generalSettingsManager = DI.get(GeneralSettingsManager.class); private final QuotedMessageMvpView view; private final MessageCompose messageCompose; @@ -111,7 +113,7 @@ public void populateUIWithQuotedMessage(MessageViewInfo messageViewInfo, boolean } // Add the HTML reply header to the top of the content. - quotedHtmlContent = HtmlQuoteCreator.quoteOriginalHtmlMessage(messageViewInfo.message, content, quoteStyle); + quotedHtmlContent = HtmlQuoteCreator.quoteOriginalHtmlMessage(messageViewInfo.message, content, quoteStyle, generalSettingsManager); // Load the message with the reply header. TODO replace with MessageViewInfo data view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt index 8e61cedde83..14e64a741f4 100644 --- a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt +++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt @@ -47,7 +47,7 @@ class GeneralSettingsDataStore( "quiet_time_enabled" -> generalSettingsManager.getSettings().isQuietTimeEnabled "disable_notifications_during_quiet_time" -> !K9.isNotificationDuringQuietTimeEnabled "privacy_hide_useragent" -> K9.isHideUserAgent - "privacy_hide_timezone" -> K9.isHideTimeZone + "privacy_hide_timezone" -> generalSettingsManager.getSettings().privacy.isHideTimeZone "debug_logging" -> K9.isDebugLoggingEnabled "sync_debug_logging" -> K9.isSyncLoggingEnabled "sensitive_logging" -> K9.isSensitiveDebugLoggingEnabled @@ -87,7 +87,7 @@ class GeneralSettingsDataStore( "quiet_time_enabled" -> setIsQuietTimeEnabled(isQuietTimeEnabled = value) "disable_notifications_during_quiet_time" -> K9.isNotificationDuringQuietTimeEnabled = !value "privacy_hide_useragent" -> K9.isHideUserAgent = value - "privacy_hide_timezone" -> K9.isHideTimeZone = value + "privacy_hide_timezone" -> setIsHideTimeZone(isHideTimeZone = value) "debug_logging" -> K9.isDebugLoggingEnabled = value "sync_debug_logging" -> K9.isSyncLoggingEnabled = value "sensitive_logging" -> K9.isSensitiveDebugLoggingEnabled = value @@ -381,6 +381,13 @@ class GeneralSettingsDataStore( ) } + private fun setIsHideTimeZone(isHideTimeZone: Boolean) { + skipSaveSettings = true + generalSettingsManager.setIsHideTimeZone( + isHideTimeZone = isHideTimeZone, + ) + } + private fun appThemeToString(theme: AppTheme) = when (theme) { AppTheme.LIGHT -> "light" AppTheme.DARK -> "dark"