Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package net.thunderbird.feature.mail.message.list.ui.effect

import net.thunderbird.feature.account.AccountId

/**
* Represents one-time side effects that can be triggered from the message list screen.
* These effects are intended to be consumed by the UI to perform actions like navigation
* or showing transient messages.
*/
sealed interface MessageListEffect {
/**
* Effect to navigate back from the current screen.
*/
data object NavigateBack : MessageListEffect

/**
* Effect to navigate to the "Move To" screen, allowing the user to select a destination
* folder for the given messages.
*
* @param messagesIds The unique identifiers of the messages to be moved.
* @param accountId The identifier of the account to which the messages belong.
*/
data class NavigateToMoveToScreen(val messagesIds: List<Long>, val accountId: AccountId) : MessageListEffect

/**
* Represents the effect of messages being successfully archived.
* This is typically used to show a notification or a snackbar to the user.
*
* @param messagesIdByAccountId A map where keys are account IDs and values are lists of message IDs
* that have been archived for that account.
*/
data class ArchivedMessages(val messagesIdByAccountId: Map<AccountId, List<Long>>) : MessageListEffect

/**
* Represents an effect for when pending (outbox) messages have been successfully sent.
*
* This effect is triggered after messages residing in the outbox are processed and sent,
* typically resulting in them being moved to the Sent folder, if any configured.
*
* @param messagesIdByAccountId A map where each key is an [AccountId] and the value is a list of
* message IDs that have been sent for that account.
*/
data class PendingMessagesSent(val messagesIdByAccountId: Map<AccountId, List<Long>>) : MessageListEffect

/**
* Represents an effect for when messages have been permanently removed (expunged) from a folder.
*
* This typically happens after messages marked for deletion are purged from the server,
* particularly with IMAP accounts. The UI should reflect this by removing these messages
* or updating its state accordingly.
*
* @param messagesIdByAccountId A map where keys are account IDs and values are lists of message IDs
* that have been expunged. This structure supports handling expunged messages from multiple accounts
* in a single operation.
*/
data class ExpungedMessages(val messagesIdByAccountId: Map<AccountId, List<Long>>) : MessageListEffect

/**
* Represents the side effect that messages have been marked for deletion.
*
* This effect is typically triggered after a user performs a delete action. The UI can use this
* to show a confirmation, such as a snackbar, indicating the successful deletion.
*
* @param messagesIdByAccountId A map where each key is an [AccountId] and the corresponding value
* is a list of message IDs that have been deleted for that account.
*/
data class DeletedMessages(val messagesIdByAccountId: Map<AccountId, List<Long>>) : MessageListEffect

/**
* Represents the effect of one or more draft messages being discarded (deleted).
*
* @param messagesIdByAccountId A map where each key is an [AccountId] and the value is a list of message IDs
* that have been discarded for that account.
*/
data class DraftsDiscarded(val messagesIdByAccountId: Map<AccountId, List<Long>>) : MessageListEffect
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package net.thunderbird.feature.mail.message.list.ui.event

import net.thunderbird.feature.mail.message.list.ui.state.Folder

/**
* Represents UI events related to folder actions, extending [MessageListEvent].
* These events are typically triggered by user interactions within a specific folder view.
*
* @see MessageListEvent
*/
sealed interface FolderEvent : MessageListEvent {
/**
* Event to expunge (permanently delete) messages marked for deletion in a specific folder.
*
* @param folder The folder from which to expunge messages.
*/
data class Expunge(val folder: Folder) : FolderEvent

/**
* Event to create a new folder to be used as the archive folder.
*
* @param name The name of the folder to be created.
*/
data class CreateArchiveFolder(val name: String) : FolderEvent

/**
* Event to assign an existing folder as the archive folder.
*
* @param folder The folder to be designated as the archive folder.
*/
data class AssignArchiveFolder(val folder: Folder) : FolderEvent

/**
* Event to mark all messages within a specific folder as read.
*
* @param folder The folder in which all messages should be marked as read.
*/
data class MarkAllMessagesAsRead(val folder: Folder) : FolderEvent
}

/**
* Represents events that are specific to the Trash folder.
*/
sealed interface TrashFolderEvent : FolderEvent {
/**
* Event to permanently delete all messages in the Trash folder.
*/
data object EmptyTrash : FolderEvent
}

/**
* Represents events that are specific to the Outbox folder.
*/
sealed interface OutboxFolderEvent : FolderEvent {
/**
* Event to trigger sending all pending messages in the Outbox.
*/
data object SendPendingMessages : FolderEvent
}

/**
* Represents events that are specific to the Spam folder.
*/
sealed interface SpamFolderEvent : FolderEvent {
/**
* Event to permanently delete all messages in the spam folder.
*/
data object EmptySpamFolder : FolderEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package net.thunderbird.feature.mail.message.list.ui.event

import net.thunderbird.core.common.action.SwipeAction
import net.thunderbird.core.common.mail.Flag
import net.thunderbird.feature.mail.message.list.ui.state.MessageItemUi

/**
* Represents events that can be triggered on a single message item in the message list, extending [MessageListEvent].
*
* @see MessageListEvent
*/
sealed interface MessageItemEvent : MessageListEvent.UserEvent {
/**
* Represents an event triggered when a user clicks on a single message item in the list.
*
* @param message The [MessageItemUi] that was clicked.
*/
data class OnMessageClick(val message: MessageItemUi) : MessageItemEvent

/**
* Event to toggle the selection state of one or more messages.
*
* @param messages The list of messages whose selection state should be toggled.
*/
data class ToggleSelectMessages(val messages: List<MessageItemUi>) : MessageItemEvent {
constructor(message: MessageItemUi) : this(messages = listOf(message))
}

/**
* Event to toggle the 'favourite' (starred) state of one or more messages.
*
* @param messages The list of [MessageItemUi]s to be toggled.
*/
data class ToggleFavourite(val messages: List<MessageItemUi>) : MessageItemEvent {
constructor(message: MessageItemUi) : this(messages = listOf(message))
}

/**
* An event to toggle the read/unread status of one or more messages.
*
* @param messages The list of messages whose read/unread status should be toggled.
*/
data class ToggleReadUnread(val messages: List<MessageItemUi>) : MessageItemEvent {
constructor(message: MessageItemUi) : this(messages = listOf(message))
}

/**
* Flags a list of messages with the given [Flag].
*
* @param messages The list of messages to flag.
* @param flag The flag to apply to the messages.
*/
data class FlagMessages(val messages: List<MessageItemUi>, val flag: Flag) : MessageItemEvent {
constructor(message: MessageItemUi, flag: Flag) : this(messages = listOf(message), flag = flag)
}

/**
* Represents a swipe action on a message item.
*
* @property message The message item that was swiped.
*/
data class OnSwipeMessage(val message: MessageItemUi, val swipeAction: SwipeAction) : MessageItemEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package net.thunderbird.feature.mail.message.list.ui.event

import net.thunderbird.core.common.action.SwipeActions
import net.thunderbird.feature.account.AccountId
import net.thunderbird.feature.mail.message.list.preferences.MessageListPreferences
import net.thunderbird.feature.mail.message.list.ui.state.MessageItemUi
import net.thunderbird.feature.mail.message.list.ui.state.SortType

/**
* Represents the events that can be triggered from the message list screen.
* These events are handled by the [MessageListViewModel] to update the UI state.
*/
sealed interface MessageListEvent {
sealed interface SystemEvent : MessageListEvent
sealed interface UserEvent : MessageListEvent

/**
* A system event to trigger the loading of initial configurations for the message list.
* This includes loading swipe actions, user preferences, and available sort types.
*/
data object LoadConfigurations : SystemEvent

/**
* A system event indicating that the swipe actions for one or more accounts have been loaded.
*
* @param swipeActions A map where the key is the [AccountId] and the value is the corresponding [SwipeActions]
* configuration for that account.
*/
data class SwipeActionsLoaded(val swipeActions: Map<AccountId, SwipeActions>) : SystemEvent

/**
* A system event to update the message list preferences.
* This is typically triggered when preferences change from an external source, like the settings screen.
*
* @param preferences The new [MessageListPreferences] to apply.
*/
data class UpdatePreferences(val preferences: MessageListPreferences) : SystemEvent

/**
* A system event indicating that the sort types for various accounts have been loaded.
*
* @param sortTypes A map where the key is the [AccountId] and the value is the corresponding [SortType].
* A `null` key represents the global or default sort type.
*/
data class SortTypesLoaded(val sortTypes: Map<AccountId?, SortType>) : SystemEvent

/**
* Signals that all initial configurations, such as preferences, swipe actions, and sort types,
* have been successfully loaded and applied. This event indicates that the system is ready
* to proceed with loading the actual message list content.
*/
data object AllConfigsReady : SystemEvent

/**
* A system event to update the progress of the loading indicator.
*
* @param progress A float value between 0.0 and 1.0 representing the loading completion percentage.
*/
data class UpdateLoadingProgress(val progress: Float) : SystemEvent

/**
* A system event indicating that a list of messages has been successfully loaded.
*
* @param messages The list of [MessageItemUi] objects to be displayed.
*/
data class MessagesLoaded(val messages: List<MessageItemUi>) : SystemEvent

/**
* Event triggered when the user initiates selection mode, usually through a long press on a message item.
*/
data object EnterSelectionMode : UserEvent

/**
* Event triggered when the user exits the message selection mode.
* This typically happens when the user deselects all messages or cancels the selection action.
*/
data object ExitSelectionMode : UserEvent

/**
* Represents the event of a user requesting to load more messages in the list.
*/
data object LoadMore : UserEvent

/**
* Triggers a refresh of the message list, fetching the latest messages from the server.
*/
data object Refresh : UserEvent

/**
* An event that is triggered when the user changes the sort order of the message list.
*
* @param sortType The new [SortType] to apply to the message list.
*/
data class ChangeSortType(val sortType: SortType) : UserEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package net.thunderbird.feature.mail.message.list.ui.event

/**
* Defines the events related to searching, extending [MessageListEvent].
* These events are typically triggered by user interactions or specific conditions.
*
* @see MessageListEvent
*/
sealed interface MessageListSearchEvent : MessageListEvent.UserEvent {
/**
* Event triggered when a user performs a search with a specific query.
*
* @param query The text string to search for within the message list.
*/
data class UpdateSearchQuery(val query: String) : MessageListSearchEvent

/**
* Represents an event to trigger a "search everywhere" action.
* This typically expands the search scope to include all folders or accounts,
* not just the currently viewed one.
*/
data object SearchEverywhere : MessageListSearchEvent

/**
* Event to trigger a remote search on the server for the current query.
*/
data object SearchRemotely : MessageListSearchEvent

/**
* Event triggered to enter in the search mode.
*/
data object EnterSearchMode : MessageListSearchEvent

/**
* Event triggered to clear the current search query and exit the search mode.
*/
data object ExitSearchMode : MessageListSearchEvent
}
Loading
Loading