diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c44bf97bfc3571fb03d2190761624ce0122eb4db..57f60423a7f3e8e038fab707b2cd95eb18263917 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,6 @@ name: Bug report description: Let us know about crashes or existing functionality not working like it should. -labels: [ "bug" ] +labels: [ "bug", "unconfirmed" ] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 491635265f9fdfac6b036d415b2272a1fecf6cab..88f0b84d1c5ad75bb6d739b3bd0cdabf8a35d344 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: Feature request description: Suggest an idea for K-9 Mail -labels: [ "enhancement" ] +labels: [ "enhancement", "unconfirmed" ] body: - type: checkboxes id: checklist diff --git a/app/core/src/main/java/com/fsck/k9/K9.kt b/app/core/src/main/java/com/fsck/k9/K9.kt index 39d697d7804913fc43fcefd9f36866beaf2c7362..62614fad24e058c076e84501a91c59231f47763d 100644 --- a/app/core/src/main/java/com/fsck/k9/K9.kt +++ b/app/core/src/main/java/com/fsck/k9/K9.kt @@ -198,11 +198,7 @@ object K9 : EarlyInit { @JvmStatic var isUseMessageViewFixedWidthFont = false - @JvmStatic - var isMessageViewReturnToList = false - - @JvmStatic - var isMessageViewShowNext = false + var messageViewPostRemoveNavigation: PostRemoveNavigation = PostRemoveNavigation.ReturnToMessageList @JvmStatic var isUseVolumeKeysForNavigation = false @@ -351,8 +347,8 @@ object K9 : EarlyInit { isChangeContactNameColor = storage.getBoolean("changeRegisteredNameColor", false) contactNameColor = storage.getInt("registeredNameColor", 0xFF1093F5.toInt()) isUseMessageViewFixedWidthFont = storage.getBoolean("messageViewFixedWidthFont", false) - isMessageViewReturnToList = storage.getBoolean("messageViewReturnToList", false) - isMessageViewShowNext = storage.getBoolean("messageViewShowNext", false) + messageViewPostRemoveNavigation = + storage.getEnum("messageViewPostDeleteAction", PostRemoveNavigation.ReturnToMessageList) isHideUserAgent = storage.getBoolean("hideUserAgent", false) isHideTimeZone = storage.getBoolean("hideTimeZone", false) @@ -432,8 +428,7 @@ object K9 : EarlyInit { editor.putBoolean("changeRegisteredNameColor", isChangeContactNameColor) editor.putInt("registeredNameColor", contactNameColor) editor.putBoolean("messageViewFixedWidthFont", isUseMessageViewFixedWidthFont) - editor.putBoolean("messageViewReturnToList", isMessageViewReturnToList) - editor.putBoolean("messageViewShowNext", isMessageViewShowNext) + editor.putEnum("messageViewPostDeleteAction", messageViewPostRemoveNavigation) editor.putBoolean("hideUserAgent", isHideUserAgent) editor.putBoolean("hideTimeZone", isHideTimeZone) @@ -586,4 +581,14 @@ object K9 : EarlyInit { Share.EXTRA_FROM = "$packageName.intent.extra.SENDER" } } + + /** + * The navigation actions that can be to performed after the user has deleted or moved a message from the message + * view screen. + */ + enum class PostRemoveNavigation { + ReturnToMessageList, + ShowPreviousMessage, + ShowNextMessage, + } } diff --git a/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java b/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java index 53e5ea3a81c1d7143b58995c8a0c56b8e04b8618..3827379b593d86b5985ddbf333c68e97d69c053d 100644 --- a/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java +++ b/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java @@ -17,6 +17,7 @@ import com.fsck.k9.FontSizes; import com.fsck.k9.K9; import com.fsck.k9.K9.BACKGROUND_OPS; import com.fsck.k9.K9.NotificationQuickDelete; +import com.fsck.k9.K9.PostRemoveNavigation; import com.fsck.k9.K9.SplitViewMode; import com.fsck.k9.SwipeAction; import com.fsck.k9.UiDensity; @@ -37,6 +38,7 @@ import com.fsck.k9.preferences.upgrader.GeneralSettingsUpgraderTo31; import com.fsck.k9.preferences.upgrader.GeneralSettingsUpgraderTo58; import com.fsck.k9.preferences.upgrader.GeneralSettingsUpgraderTo69; import com.fsck.k9.preferences.upgrader.GeneralSettingsUpgraderTo79; +import com.fsck.k9.preferences.upgrader.GeneralSettingsUpgraderTo89; import static com.fsck.k9.K9.LockScreenNotificationVisibility; @@ -138,10 +140,12 @@ public class GeneralSettingsDescriptions { new V(1, new BooleanSetting(false)) )); s.put("messageViewReturnToList", Settings.versions( - new V(1, new BooleanSetting(false)) + new V(1, new BooleanSetting(false)), + new V(89, null) )); s.put("messageViewShowNext", Settings.versions( - new V(1, new BooleanSetting(false)) + new V(1, new BooleanSetting(false)), + new V(89, null) )); s.put("quietTimeEnabled", Settings.versions( new V(1, new BooleanSetting(false)) @@ -289,6 +293,9 @@ public class GeneralSettingsDescriptions { s.put("fontSizeMessageViewAccountName", Settings.versions( new V(87, new FontSizeSetting(FontSizes.FONT_DEFAULT)) )); + s.put("messageViewPostDeleteAction", Settings.versions( + new V(89, new EnumSetting<>(PostRemoveNavigation.class, PostRemoveNavigation.ReturnToMessageList)) + )); SETTINGS = Collections.unmodifiableMap(s); @@ -298,6 +305,7 @@ public class GeneralSettingsDescriptions { u.put(58, new GeneralSettingsUpgraderTo58()); u.put(69, new GeneralSettingsUpgraderTo69()); u.put(79, new GeneralSettingsUpgraderTo79()); + u.put(89, new GeneralSettingsUpgraderTo89()); UPGRADERS = Collections.unmodifiableMap(u); } diff --git a/app/core/src/main/java/com/fsck/k9/preferences/Settings.java b/app/core/src/main/java/com/fsck/k9/preferences/Settings.java index 3e617a5ec42eeea4f1b7ce58084ed24ccf07962f..e07e1f1b492de0c16059d851371fcf5e2335c3a5 100644 --- a/app/core/src/main/java/com/fsck/k9/preferences/Settings.java +++ b/app/core/src/main/java/com/fsck/k9/preferences/Settings.java @@ -36,7 +36,7 @@ public class Settings { * * @see SettingsExporter */ - public static final int VERSION = 88; + public static final int VERSION = 89; static Map validate(int version, Map> settings, Map importedSettings, boolean useDefaultValues) { diff --git a/app/core/src/main/java/com/fsck/k9/preferences/upgrader/GeneralSettingsUpgraderTo89.kt b/app/core/src/main/java/com/fsck/k9/preferences/upgrader/GeneralSettingsUpgraderTo89.kt new file mode 100644 index 0000000000000000000000000000000000000000..9a8c254dee6f5faf6b0683b42b2301b41490e9e4 --- /dev/null +++ b/app/core/src/main/java/com/fsck/k9/preferences/upgrader/GeneralSettingsUpgraderTo89.kt @@ -0,0 +1,23 @@ +package com.fsck.k9.preferences.upgrader + +import com.fsck.k9.preferences.Settings.SettingsUpgrader + +/** + * Combine `messageViewReturnToList` and `messageViewShowNext` into `messageViewPostDeleteAction`. + */ +class GeneralSettingsUpgraderTo89 : SettingsUpgrader { + override fun upgrade(settings: MutableMap): Set { + val messageViewReturnToList = settings["messageViewReturnToList"] as? Boolean + val messageViewShowNext = settings["messageViewShowNext"] as? Boolean + + if (messageViewReturnToList == true) { + settings["messageViewPostDeleteAction"] = "ReturnToMessageList" + } else if (messageViewShowNext == true) { + settings["messageViewPostDeleteAction"] = "ShowNextMessage" + } else { + settings["messageViewPostDeleteAction"] = "ShowPreviousMessage" + } + + return setOf("messageViewReturnToList", "messageViewShowNext") + } +} diff --git a/app/core/src/main/res/values/arrays_general_settings_values.xml b/app/core/src/main/res/values/arrays_general_settings_values.xml index 95fca883f9a8e088db0092e1c61324e4b3d0d546..98090fc646cab35d7359fe96c9e8aa03c9ceb065 100644 --- a/app/core/src/main/res/values/arrays_general_settings_values.xml +++ b/app/core/src/main/res/values/arrays_general_settings_values.xml @@ -221,4 +221,10 @@ move + + ReturnToMessageList + ShowPreviousMessage + ShowNextMessage + + diff --git a/app/storage/src/main/java/com/fsck/k9/preferences/K9StoragePersister.java b/app/storage/src/main/java/com/fsck/k9/preferences/K9StoragePersister.java index a3f9003e2835a145bda481e749de3d9637c134f9..e3f19a5c8af734cc68444287256d01df36d75952 100644 --- a/app/storage/src/main/java/com/fsck/k9/preferences/K9StoragePersister.java +++ b/app/storage/src/main/java/com/fsck/k9/preferences/K9StoragePersister.java @@ -21,7 +21,7 @@ import timber.log.Timber; public class K9StoragePersister implements StoragePersister { - private static final int DB_VERSION = 20; + private static final int DB_VERSION = 21; private static final String DB_NAME = "preferences_storage"; private final Context context; diff --git a/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrationTo21.kt b/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrationTo21.kt new file mode 100644 index 0000000000000000000000000000000000000000..11794e94361eb6228e5586c90d344ae0d5e51bf5 --- /dev/null +++ b/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrationTo21.kt @@ -0,0 +1,26 @@ +package com.fsck.k9.preferences.migrations + +import android.database.sqlite.SQLiteDatabase + +/** + * Combine `messageViewReturnToList` and `messageViewShowNext` into `messageViewPostDeleteAction`. + */ +class StorageMigrationTo21( + private val db: SQLiteDatabase, + private val migrationsHelper: StorageMigrationsHelper, +) { + fun createPostRemoveNavigationSetting() { + val messageViewReturnToList = migrationsHelper.readValue(db, "messageViewReturnToList").toBoolean() + val messageViewShowNext = migrationsHelper.readValue(db, "messageViewShowNext").toBoolean() + + val postRemoveNavigation = when { + messageViewReturnToList -> "ReturnToMessageList" + messageViewShowNext -> "ShowNextMessage" + else -> "ShowPreviousMessage" + } + + migrationsHelper.writeValue(db, "messageViewPostDeleteAction", postRemoveNavigation) + migrationsHelper.writeValue(db, "messageViewReturnToList", null) + migrationsHelper.writeValue(db, "messageViewShowNext", null) + } +} diff --git a/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrations.kt b/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrations.kt index d6ff640d395983062902bd106188c59b3b56f6b5..ebddafd6c4cce688f6f65d1b74938711eaf2e73d 100644 --- a/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrations.kt +++ b/app/storage/src/main/java/com/fsck/k9/preferences/migrations/StorageMigrations.kt @@ -3,6 +3,7 @@ package com.fsck.k9.preferences.migrations import android.database.sqlite.SQLiteDatabase internal object StorageMigrations { + @Suppress("MagicNumber", "CyclomaticComplexMethod") @JvmStatic fun upgradeDatabase(db: SQLiteDatabase, migrationsHelper: StorageMigrationsHelper) { val oldVersion = db.version @@ -26,5 +27,6 @@ internal object StorageMigrations { if (oldVersion < 18) StorageMigrationTo18(db, migrationsHelper).rewriteImapCompressionSettings() if (oldVersion < 19) StorageMigrationTo19(db, migrationsHelper).markGmailAccounts() if (oldVersion < 20) StorageMigrationTo20(db, migrationsHelper).fixIdentities() + if (oldVersion < 21) StorageMigrationTo21(db, migrationsHelper).createPostRemoveNavigationSetting() } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index c5fc82bad9393434ad92185a556bab03b558f58c..c69155036675d5f16abb5fba26b67baf2c07b7f1 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -52,6 +52,7 @@ import app.k9mail.core.android.common.accountmanager.AccountManagerConstants import app.k9mail.feature.launcher.FeatureLauncherActivity import com.fsck.k9.Account import com.fsck.k9.K9 +import com.fsck.k9.K9.PostRemoveNavigation import com.fsck.k9.K9.SplitViewMode import com.fsck.k9.Preferences import com.fsck.k9.account.AccountCreatorHelper @@ -78,7 +79,6 @@ import com.fsck.k9.ui.managefolders.ManageFoldersActivity import com.fsck.k9.ui.messagelist.DefaultFolderProvider import com.fsck.k9.ui.messagelist.MessageListFragment import com.fsck.k9.ui.messagelist.MessageListFragment.MessageListFragmentListener -import com.fsck.k9.ui.messageview.Direction import com.fsck.k9.ui.messageview.MessageViewContainerFragment import com.fsck.k9.ui.messageview.MessageViewContainerFragment.MessageViewContainerListener import com.fsck.k9.ui.messageview.MessageViewFragment.MessageViewFragmentListener @@ -137,12 +137,6 @@ open class MessageList : private var search: LocalSearch? = null private var singleFolderMode = false - private val lastDirection: Direction - get() { - return messageViewContainerFragment?.lastDirection - ?: if (K9.isMessageViewShowNext) Direction.NEXT else Direction.PREVIOUS - } - private var messageListActivityConfig: MessageListActivityConfig? = null /** @@ -1195,9 +1189,11 @@ open class MessageList : messageListFragment.setActiveMessage(messageReference) } - override fun showNextMessageOrReturn() { - if (K9.isMessageViewReturnToList || !showLogicalNextMessage()) { - returnToMessageList() + override fun performNavigationAfterMessageRemoval() { + when (K9.messageViewPostRemoveNavigation) { + PostRemoveNavigation.ReturnToMessageList -> returnToMessageList() + PostRemoveNavigation.ShowPreviousMessage -> showPreviousMessageOrReturn() + PostRemoveNavigation.ShowNextMessage -> showNextMessageOrReturn() } } @@ -1209,16 +1205,15 @@ open class MessageList : } } - private fun showLogicalNextMessage(): Boolean { - val couldMoveInLastDirection = when (lastDirection) { - Direction.NEXT -> showNextMessage() - Direction.PREVIOUS -> showPreviousMessage() + private fun showPreviousMessageOrReturn() { + if (!showPreviousMessage()) { + returnToMessageList() } + } - return if (couldMoveInLastDirection) { - true - } else { - showNextMessage() || showPreviousMessage() + private fun showNextMessageOrReturn() { + if (!showNextMessage()) { + returnToMessageList() } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt index cc078b0cdc04b8f6bba346b9d457e20d1ac8dd13..817bac7bdfff4ab192fa3df75e1f9c118c58be45 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt @@ -426,7 +426,7 @@ class MessageViewFragment : private fun delete() { disableDeleteMenuItem() - fragmentListener.showNextMessageOrReturn() + fragmentListener.performNavigationAfterMessageRemoval() messagingController.deleteMessage(messageReference) } @@ -455,7 +455,7 @@ class MessageViewFragment : } private fun refileMessage(destinationFolderId: Long) { - fragmentListener.showNextMessageOrReturn() + fragmentListener.performNavigationAfterMessageRemoval() val sourceFolderId = messageReference.folderId messagingController.moveMessage(account, sourceFolderId, messageReference, destinationFolderId) @@ -528,7 +528,7 @@ class MessageViewFragment : } private fun onMoveToDrafts() { - fragmentListener.showNextMessageOrReturn() + fragmentListener.performNavigationAfterMessageRemoval() val account = account val folderId = messageReference.folderId @@ -614,7 +614,7 @@ class MessageViewFragment : account.setLastSelectedFolderId(destinationFolderId) - fragmentListener.showNextMessageOrReturn() + fragmentListener.performNavigationAfterMessageRemoval() moveMessage(messageReference, destinationFolderId) } @@ -864,7 +864,7 @@ class MessageViewFragment : fun onReplyAll(messageReference: MessageReference, decryptionResultForReply: Parcelable?) fun onReply(messageReference: MessageReference, decryptionResultForReply: Parcelable?) fun setProgress(enable: Boolean) - fun showNextMessageOrReturn() + fun performNavigationAfterMessageRemoval() } private val messageLoaderCallbacks: MessageLoaderCallbacks = object : MessageLoaderCallbacks { diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt index 1fd9d4814d3db3ea945489294a43f54fa5b2e001..a35d036b1dd704a6ea2ada3477c1ae0ffb5efe40 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt @@ -2,6 +2,7 @@ package com.fsck.k9.ui.settings.general import androidx.preference.PreferenceDataStore import com.fsck.k9.K9 +import com.fsck.k9.K9.PostRemoveNavigation import com.fsck.k9.SwipeAction import com.fsck.k9.UiDensity import com.fsck.k9.job.K9JobManager @@ -36,8 +37,6 @@ class GeneralSettingsDataStore( "threaded_view" -> K9.isThreadedViewEnabled "messageview_fixedwidth_font" -> K9.isUseMessageViewFixedWidthFont "messageview_autofit_width" -> K9.isAutoFitWidth - "messageview_return_to_list" -> K9.isMessageViewReturnToList - "messageview_show_next" -> K9.isMessageViewShowNext "quiet_time_enabled" -> K9.isQuietTimeEnabled "disable_notifications_during_quiet_time" -> !K9.isNotificationDuringQuietTimeEnabled "sent_sound_enabled" -> K9.isSentSoundEnabled @@ -68,8 +67,6 @@ class GeneralSettingsDataStore( "threaded_view" -> K9.isThreadedViewEnabled = value "messageview_fixedwidth_font" -> K9.isUseMessageViewFixedWidthFont = value "messageview_autofit_width" -> K9.isAutoFitWidth = value - "messageview_return_to_list" -> K9.isMessageViewReturnToList = value - "messageview_show_next" -> K9.isMessageViewShowNext = value "quiet_time_enabled" -> K9.isQuietTimeEnabled = value "disable_notifications_during_quiet_time" -> K9.isNotificationDuringQuietTimeEnabled = !value "sent_sound_enabled" -> K9.isSentSoundEnabled = value @@ -128,6 +125,7 @@ class GeneralSettingsDataStore( "swipe_action_right" -> swipeActionToString(K9.swipeRightAction) "swipe_action_left" -> swipeActionToString(K9.swipeLeftAction) "message_list_density" -> K9.messageListDensity.toString() + "post_remove_navigation" -> K9.messageViewPostRemoveNavigation.name else -> defValue } } @@ -164,6 +162,7 @@ class GeneralSettingsDataStore( "swipe_action_right" -> K9.swipeRightAction = stringToSwipeAction(value) "swipe_action_left" -> K9.swipeLeftAction = stringToSwipeAction(value) "message_list_density" -> K9.messageListDensity = UiDensity.valueOf(value) + "post_remove_navigation" -> K9.messageViewPostRemoveNavigation = PostRemoveNavigation.valueOf(value) else -> return } diff --git a/app/ui/legacy/src/main/res/values/arrays_general_settings_strings.xml b/app/ui/legacy/src/main/res/values/arrays_general_settings_strings.xml index 213f6ea87d0776327e2a9a55948c246e76fbf5db..76f0980d458d59301b584bce975cb2db7a1f3ed3 100644 --- a/app/ui/legacy/src/main/res/values/arrays_general_settings_strings.xml +++ b/app/ui/legacy/src/main/res/values/arrays_general_settings_strings.xml @@ -174,4 +174,10 @@ @string/general_settings_ui_density_relaxed + + @string/general_settings_post_remove_action_return_to_list + @string/general_settings_post_remove_action_show_previous_message + @string/general_settings_post_remove_action_show_next_message + + diff --git a/app/ui/legacy/src/main/res/values/strings.xml b/app/ui/legacy/src/main/res/values/strings.xml index 409091f92088c70e4fdae0f3c66aecf50dc23a0a..fe68e02c3e33c4a69a9452efc9f82337136e01c5 100644 --- a/app/ui/legacy/src/main/res/values/strings.xml +++ b/app/ui/legacy/src/main/res/values/strings.xml @@ -232,6 +232,13 @@ Return to message list after message deletion Show next message after delete Show next message by default after message deletion + + + After deleting or moving a message + Return to message list + Show previous message + Show next message + Confirm actions Show a dialog whenever you perform selected actions Delete @@ -1119,4 +1126,4 @@ You can keep this message and use it as a backup for your secret key. If you wan Removing account… unread, %s - \ No newline at end of file +