Merge conversaions and messages flow together.
MAILAND-1971
This commit is contained in:
parent
43b5552b07
commit
9f9af0d14c
|
@ -37,7 +37,7 @@ class MailboxRecyclerViewAdapter(
|
|||
private val onSelectionModeChange: ((SelectionModeEnum) -> Unit)?
|
||||
) : RecyclerView.Adapter<MailboxItemViewHolder>() {
|
||||
|
||||
private var mMailboxLocation = Constants.MessageLocationType.INVALID
|
||||
private var mailboxLocation = Constants.MessageLocationType.INVALID
|
||||
|
||||
private var labels = mapOf<String, Label>()
|
||||
private val mailboxItems = mutableListOf<MailboxUiItem>()
|
||||
|
@ -160,7 +160,7 @@ class MailboxRecyclerViewAdapter(
|
|||
this.view.bind(
|
||||
mailboxItem,
|
||||
selectedMailboxItemsIds.isNotEmpty(),
|
||||
mMailboxLocation,
|
||||
mailboxLocation,
|
||||
isBeingSent,
|
||||
isAttachmentsBeingUploaded
|
||||
)
|
||||
|
@ -212,8 +212,8 @@ class MailboxRecyclerViewAdapter(
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setNewLocation(mailboxLocation: Constants.MessageLocationType) {
|
||||
mMailboxLocation = mailboxLocation
|
||||
fun setNewLocation(locationType: Constants.MessageLocationType) {
|
||||
mailboxLocation = locationType
|
||||
}
|
||||
|
||||
fun getOldestMailboxItemTimestamp(): Long {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package ch.protonmail.android.events;
|
||||
|
||||
@Deprecated // unused, no subscribers
|
||||
public class FetchUpdatesEvent {
|
||||
public final Status status;
|
||||
|
||||
|
|
|
@ -45,11 +45,8 @@ import android.widget.Toast
|
|||
import androidx.activity.viewModels
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.distinctUntilChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.switchMap
|
||||
import androidx.loader.app.LoaderManager
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
|
@ -105,7 +102,6 @@ import ch.protonmail.android.data.local.model.TotalLabelCounter
|
|||
import ch.protonmail.android.data.local.model.TotalLocationCounter
|
||||
import ch.protonmail.android.details.presentation.MessageDetailsActivity
|
||||
import ch.protonmail.android.events.FetchLabelsEvent
|
||||
import ch.protonmail.android.events.FetchUpdatesEvent
|
||||
import ch.protonmail.android.events.MailboxLoadedEvent
|
||||
import ch.protonmail.android.events.MailboxNoMessagesEvent
|
||||
import ch.protonmail.android.events.MessageCountsEvent
|
||||
|
@ -203,7 +199,7 @@ class MailboxActivity :
|
|||
|
||||
private lateinit var mailboxAdapter: MailboxRecyclerViewAdapter
|
||||
private var swipeController: SwipeController = SwipeController()
|
||||
private val mailboxLocationMain = MutableLiveData<MessageLocationType>()
|
||||
|
||||
private val isLoadingMore = AtomicBoolean(false)
|
||||
private var scrollStateChanged = false
|
||||
private var actionMode: ActionMode? = null
|
||||
|
@ -242,13 +238,12 @@ class MailboxActivity :
|
|||
if (!userManager.isEngagementShown) {
|
||||
startActivity(AppUtil.decorInAppIntent(Intent(this, EngagementActivity::class.java)))
|
||||
}
|
||||
mailboxLocationMain.value = MessageLocationType.INBOX
|
||||
// Set the padding to match the Status Bar height
|
||||
if (savedInstanceState != null) {
|
||||
val locationInt = savedInstanceState.getInt(STATE_MAILBOX_LOCATION)
|
||||
mailboxLabelId = savedInstanceState.getString(STATE_MAILBOX_LABEL_LOCATION)
|
||||
mailboxLabelName = savedInstanceState.getString(STATE_MAILBOX_LABEL_LOCATION_NAME)
|
||||
mailboxLocationMain.value = fromInt(locationInt)
|
||||
setMailboxLocation(fromInt(locationInt))
|
||||
}
|
||||
if (extras != null && extras.containsKey(EXTRA_MAILBOX_LOCATION)) {
|
||||
switchToMailboxLocation(extras.getInt(EXTRA_MAILBOX_LOCATION))
|
||||
|
@ -330,8 +325,7 @@ class MailboxActivity :
|
|||
)
|
||||
settingsIntent.putExtra(
|
||||
EXTRA_CURRENT_MAILBOX_LOCATION,
|
||||
if (mailboxLocationMain.value != null) mailboxLocationMain.value!!.messageLocationTypeValue
|
||||
else MessageLocationType.INBOX.messageLocationTypeValue
|
||||
mailboxViewModel.mailboxLocation.value.messageLocationTypeValue
|
||||
)
|
||||
settingsIntent.putExtra(EXTRA_CURRENT_MAILBOX_LABEL_ID, mailboxLabelId)
|
||||
startActivity(settingsIntent)
|
||||
|
@ -372,7 +366,10 @@ class MailboxActivity :
|
|||
|
||||
observeMailboxItemsByLocation(syncId = syncUUID, includeLabels = true)
|
||||
|
||||
mailboxLocationMain.observe(this, mailboxAdapter::setNewLocation)
|
||||
mailboxViewModel.mailboxLocation
|
||||
.onEach { mailboxAdapter.setNewLocation(it) }
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
ItemTouchHelper(swipeController).attachToRecyclerView(mailboxRecyclerView)
|
||||
|
||||
setUpMailboxActionsView()
|
||||
|
@ -568,31 +565,38 @@ class MailboxActivity :
|
|||
refreshMessages: Boolean = false,
|
||||
syncId: String
|
||||
) {
|
||||
mailboxLocationMain.switchMap { location ->
|
||||
mailboxViewModel.getMailboxItems(
|
||||
location,
|
||||
mailboxLabelId,
|
||||
includeLabels,
|
||||
syncId,
|
||||
refreshMessages
|
||||
)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.observe(this) { state ->
|
||||
Timber.v("New mailbox state: $state")
|
||||
setLoadingMore(false)
|
||||
setRefreshing(false)
|
||||
if (state.error.isNotEmpty()) {
|
||||
Timber.e("Mailbox error ${state.error}")
|
||||
Toast.makeText(this, getString(R.string.error_loading_conversations), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
mailboxViewModel.getMailboxItems(
|
||||
mailboxLabelId,
|
||||
includeLabels,
|
||||
syncId,
|
||||
refreshMessages
|
||||
)
|
||||
|
||||
mailboxViewModel.mailboxState
|
||||
.onEach { renderState(it) }
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
||||
|
||||
private fun renderState(state: MailboxState) {
|
||||
Timber.v("New mailbox state: $state")
|
||||
setLoadingMore(false)
|
||||
setRefreshing(false)
|
||||
|
||||
when (state) {
|
||||
is MailboxState.Loading -> setRefreshing(true)
|
||||
is MailboxState.Data -> {
|
||||
include_mailbox_no_messages.isVisible = state.items.isEmpty()
|
||||
mailboxRecyclerView.isVisible != state.items.isEmpty()
|
||||
|
||||
mailboxAdapter.clear()
|
||||
mailboxAdapter.addAll(state.items)
|
||||
}
|
||||
is MailboxState.Error -> {
|
||||
Timber.e(state.throwable, "Mailbox error ${state.error}")
|
||||
Toast.makeText(this, getString(R.string.error_loading_conversations), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val listScrollListener: RecyclerView.OnScrollListener = object : RecyclerView.OnScrollListener() {
|
||||
|
@ -628,9 +632,8 @@ class MailboxActivity :
|
|||
refreshMessages: Boolean = false,
|
||||
oldestItemTimestamp: Long = now()
|
||||
) {
|
||||
val mailboxLocation = mailboxLocationMain.value ?: MessageLocationType.INBOX
|
||||
|
||||
mailboxViewModel.loadMailboxItems(
|
||||
mailboxLocation,
|
||||
mailboxLabelId,
|
||||
includeLabels,
|
||||
syncUUID,
|
||||
|
@ -757,7 +760,7 @@ class MailboxActivity :
|
|||
checkDelinquency()
|
||||
mailboxViewModel.checkConnectivity()
|
||||
swipeController.loadCurrentMailSetting()
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
val mailboxLocation = mailboxViewModel.mailboxLocation.value
|
||||
if (mailboxLocation == MessageLocationType.INBOX) {
|
||||
AppUtil.clearNotifications(this, userManager.requireCurrentUserId())
|
||||
}
|
||||
|
@ -778,11 +781,7 @@ class MailboxActivity :
|
|||
public override fun onSaveInstanceState(outState: Bundle) {
|
||||
outState.putInt(
|
||||
STATE_MAILBOX_LOCATION,
|
||||
if (mailboxLocationMain.value != null) {
|
||||
mailboxLocationMain.value!!.messageLocationTypeValue
|
||||
} else {
|
||||
MessageLocationType.INBOX.messageLocationTypeValue
|
||||
}
|
||||
mailboxViewModel.mailboxLocation.value.messageLocationTypeValue
|
||||
)
|
||||
outState.putString(STATE_MAILBOX_LABEL_LOCATION, mailboxLabelId)
|
||||
outState.putString(STATE_MAILBOX_LABEL_LOCATION_NAME, mailboxLabelName)
|
||||
|
@ -809,7 +808,7 @@ class MailboxActivity :
|
|||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_mailbox_options, menu)
|
||||
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
val mailboxLocation = mailboxViewModel.mailboxLocation.value
|
||||
menu.findItem(R.id.empty).isVisible =
|
||||
mailboxLocation in listOf(MessageLocationType.DRAFT, MessageLocationType.SPAM, MessageLocationType.TRASH)
|
||||
return true
|
||||
|
@ -819,7 +818,7 @@ class MailboxActivity :
|
|||
menu.clear()
|
||||
menuInflater.inflate(R.menu.menu_mailbox_options, menu)
|
||||
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
val mailboxLocation = mailboxViewModel.mailboxLocation.value
|
||||
menu.findItem(R.id.empty).isVisible =
|
||||
mailboxLocation in listOf(
|
||||
MessageLocationType.DRAFT,
|
||||
|
@ -841,7 +840,7 @@ class MailboxActivity :
|
|||
leftStringId = R.string.no
|
||||
) {
|
||||
setRefreshing(true)
|
||||
mJobManager.addJobInBackground(EmptyFolderJob(mailboxLocationMain.value, this.mailboxLabelId))
|
||||
mJobManager.addJobInBackground(EmptyFolderJob(mailboxViewModel.mailboxLocation.value, this.mailboxLabelId))
|
||||
setLoadingMore(false)
|
||||
}
|
||||
}
|
||||
|
@ -854,7 +853,7 @@ class MailboxActivity :
|
|||
override fun onBackPressed() {
|
||||
saveLastInteraction()
|
||||
val drawerClosed = closeDrawer()
|
||||
if (!drawerClosed && mailboxLocationMain.value != MessageLocationType.INBOX) {
|
||||
if (!drawerClosed && mailboxViewModel.mailboxLocation.value != MessageLocationType.INBOX) {
|
||||
switchToMailboxLocation(DrawerOptionType.INBOX.drawerOptionTypeValue)
|
||||
} else if (!drawerClosed) {
|
||||
moveTaskToBack(true)
|
||||
|
@ -891,14 +890,10 @@ class MailboxActivity :
|
|||
}
|
||||
|
||||
override val currentMailboxLocation: MessageLocationType
|
||||
get() = if (mailboxLocationMain.value != null) {
|
||||
mailboxLocationMain.value!!
|
||||
} else {
|
||||
MessageLocationType.INBOX
|
||||
}
|
||||
get() = mailboxViewModel.mailboxLocation.value
|
||||
|
||||
private fun setTitle() {
|
||||
val titleRes: Int = when (mailboxLocationMain.value) {
|
||||
val titleRes: Int = when (mailboxViewModel.mailboxLocation.value) {
|
||||
MessageLocationType.INBOX -> R.string.inbox_option
|
||||
MessageLocationType.STARRED -> R.string.starred_option
|
||||
MessageLocationType.DRAFT -> R.string.drafts_option
|
||||
|
@ -925,7 +920,6 @@ class MailboxActivity :
|
|||
onRetryClick = ::onConnectivityCheckRetry,
|
||||
isOffline = connectivity == Constants.ConnectionState.NO_INTERNET
|
||||
).show()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -955,7 +949,7 @@ class MailboxActivity :
|
|||
if (!isDohOngoing) {
|
||||
showToast(event.status)
|
||||
}
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
val mailboxLocation = mailboxViewModel.mailboxLocation.value
|
||||
val setOfLabels =
|
||||
setOf(
|
||||
MessageLocationType.LABEL,
|
||||
|
@ -963,7 +957,7 @@ class MailboxActivity :
|
|||
MessageLocationType.LABEL_OFFLINE
|
||||
)
|
||||
if (event.status == Status.NO_NETWORK && setOfLabels.any { it == mailboxLocation }) {
|
||||
mailboxLocationMain.value = MessageLocationType.LABEL_OFFLINE
|
||||
setMailboxLocation(MessageLocationType.LABEL_OFFLINE)
|
||||
}
|
||||
mNetworkResults.setMailboxLoaded(MailboxLoadedEvent(Status.SUCCESS, null))
|
||||
}
|
||||
|
@ -993,10 +987,6 @@ class MailboxActivity :
|
|||
setLoadingMore(false)
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onUpdatesLoaded(event: FetchUpdatesEvent?) {
|
||||
}
|
||||
|
||||
private fun showToast(status: Status) {
|
||||
when (status) {
|
||||
Status.UNAUTHORIZED -> {
|
||||
|
@ -1280,7 +1270,7 @@ class MailboxActivity :
|
|||
mailboxLabelId = null
|
||||
invalidateOptionsMenu()
|
||||
syncUUID = UUID.randomUUID().toString()
|
||||
mailboxLocationMain.value = newMessageLocationType
|
||||
setMailboxLocation(newMessageLocationType)
|
||||
setTitle()
|
||||
closeDrawer(animate = false)
|
||||
mailboxRecyclerView.clearFocus()
|
||||
|
@ -1389,6 +1379,10 @@ class MailboxActivity :
|
|||
return true
|
||||
}
|
||||
|
||||
private fun setMailboxLocation(locationToSet: MessageLocationType) {
|
||||
mailboxViewModel.setNewMailboxLocation(locationToSet)
|
||||
}
|
||||
|
||||
private val fcmBroadcastReceiver: BroadcastReceiver = FcmBroadcastReceiver()
|
||||
|
||||
private class OnMessageClickTask internal constructor(
|
||||
|
@ -1487,7 +1481,7 @@ class MailboxActivity :
|
|||
}
|
||||
mailboxActivity.mailboxLabelId = labelId
|
||||
mailboxActivity.mailboxLabelName = labelName
|
||||
mailboxActivity.mailboxLocationMain.value = locationToSet
|
||||
mailboxActivity.setMailboxLocation(locationToSet)
|
||||
if (label != null) {
|
||||
val actionBar = mailboxActivity.supportActionBar
|
||||
if (actionBar != null) {
|
||||
|
@ -1554,8 +1548,8 @@ class MailboxActivity :
|
|||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
if (viewHolder is MessageViewHolder) {
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
return if (mailboxLocationMain.value != null && mailboxLocation == MessageLocationType.DRAFT ||
|
||||
val mailboxLocation = currentMailboxLocation
|
||||
return if (mailboxLocation == MessageLocationType.DRAFT ||
|
||||
mailboxLocation == MessageLocationType.ALL_DRAFT
|
||||
) {
|
||||
makeMovementFlags(0, 0)
|
||||
|
@ -1594,14 +1588,14 @@ class MailboxActivity :
|
|||
val position = viewHolder.adapterPosition
|
||||
val mailboxItem = mailboxAdapter.getItem(position)
|
||||
val messageSwiped = SimpleMessage(mailboxItem)
|
||||
val mailboxLocation = mailboxLocationMain.value
|
||||
val mailboxLocation = currentMailboxLocation
|
||||
val settings = mailSettings ?: return
|
||||
val swipeActionOrdinal: Int = when (direction) {
|
||||
ItemTouchHelper.RIGHT -> settings.rightSwipeAction
|
||||
ItemTouchHelper.LEFT -> settings.leftSwipeAction
|
||||
else -> throw IllegalArgumentException("Unrecognised direction: $direction")
|
||||
}
|
||||
val swipeAction = normalise(SwipeAction.values()[swipeActionOrdinal], mailboxLocationMain.value)
|
||||
val swipeAction = normalise(SwipeAction.values()[swipeActionOrdinal], currentMailboxLocation)
|
||||
mSwipeProcessor.handleSwipe(swipeAction, messageSwiped, mJobManager, mailboxLabelId)
|
||||
if (undoSnack != null && undoSnack!!.isShownOrQueued) {
|
||||
undoSnack!!.dismiss()
|
||||
|
@ -1616,7 +1610,7 @@ class MailboxActivity :
|
|||
},
|
||||
true
|
||||
)
|
||||
if (!(swipeAction == SwipeAction.TRASH && mailboxLocationMain.value == MessageLocationType.DRAFT)) {
|
||||
if (!(swipeAction == SwipeAction.TRASH && currentMailboxLocation == MessageLocationType.DRAFT)) {
|
||||
undoSnack!!.show()
|
||||
}
|
||||
if (swipeCustomizeSnack != null && !customizeSwipeSnackShown) {
|
||||
|
@ -1642,7 +1636,7 @@ class MailboxActivity :
|
|||
val height = itemView.bottom - itemView.top
|
||||
val width = itemView.right - itemView.left
|
||||
val layoutId: Int = when {
|
||||
mailboxLocationMain.value == MessageLocationType.DRAFT -> {
|
||||
currentMailboxLocation == MessageLocationType.DRAFT -> {
|
||||
SwipeAction.TRASH.getActionBackgroundResource(deltaX < 0)
|
||||
}
|
||||
deltaX < 0 -> {
|
||||
|
@ -1697,7 +1691,7 @@ class MailboxActivity :
|
|||
) {
|
||||
mailboxActivity.checkUserAndFetchNews()
|
||||
}
|
||||
if (mailboxActivity.mailboxLocationMain.value == location) {
|
||||
if (mailboxActivity.currentMailboxLocation == location) {
|
||||
mailboxActivity.refreshEmptyView(total)
|
||||
foundMailbox = true
|
||||
}
|
||||
|
|
|
@ -22,8 +22,15 @@ package ch.protonmail.android.mailbox.presentation
|
|||
import ch.protonmail.android.mailbox.presentation.model.MailboxUiItem
|
||||
import me.proton.core.util.kotlin.EMPTY_STRING
|
||||
|
||||
data class MailboxState(
|
||||
val items: List<MailboxUiItem> = emptyList(),
|
||||
val error: String = EMPTY_STRING,
|
||||
val noMoreItems: Boolean = false
|
||||
)
|
||||
sealed class MailboxState {
|
||||
object Loading : MailboxState()
|
||||
data class Error(
|
||||
val error: String = EMPTY_STRING,
|
||||
val throwable: Throwable?
|
||||
) : MailboxState()
|
||||
|
||||
data class Data(
|
||||
val items: List<MailboxUiItem> = emptyList(),
|
||||
val noMoreItems: Boolean = false
|
||||
) : MailboxState()
|
||||
}
|
||||
|
|
|
@ -21,9 +21,7 @@ package ch.protonmail.android.mailbox.presentation
|
|||
import android.graphics.Color
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.switchMap
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import ch.protonmail.android.activities.messageDetails.repository.MessageDetailsRepository
|
||||
import ch.protonmail.android.api.NetworkConfigurator
|
||||
|
@ -70,8 +68,16 @@ import ch.protonmail.android.utils.UserUtils
|
|||
import ch.protonmail.android.viewmodel.ConnectivityBaseViewModel
|
||||
import com.birbit.android.jobqueue.JobManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -116,6 +122,8 @@ class MailboxViewModel @Inject constructor(
|
|||
private val _manageLimitReachedWarningOnTryCompose = MutableLiveData<Event<Boolean>>()
|
||||
private val _toastMessageMaxLabelsReached = MutableLiveData<Event<MaxLabelsReached>>()
|
||||
private val _hasSuccessfullyDeletedMessages = MutableLiveData<Boolean>()
|
||||
private val _mailboxState = MutableStateFlow<MailboxState>(MailboxState.Loading)
|
||||
private val _mailboxLocation = MutableStateFlow(INBOX)
|
||||
|
||||
val manageLimitReachedWarning: LiveData<Event<Boolean>>
|
||||
get() = _manageLimitReachedWarning
|
||||
|
@ -131,6 +139,12 @@ class MailboxViewModel @Inject constructor(
|
|||
val hasSuccessfullyDeletedMessages: LiveData<Boolean>
|
||||
get() = _hasSuccessfullyDeletedMessages
|
||||
|
||||
val mailboxState: StateFlow<MailboxState>
|
||||
get() = _mailboxState
|
||||
|
||||
val mailboxLocation: StateFlow<Constants.MessageLocationType>
|
||||
get() = _mailboxLocation
|
||||
|
||||
fun reloadDependenciesForUser() {
|
||||
pendingSendsLiveData = messageDetailsRepository.findAllPendingSendsAsync()
|
||||
pendingUploadsLiveData = messageDetailsRepository.findAllPendingUploadsAsync()
|
||||
|
@ -228,38 +242,64 @@ class MailboxViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun getMailboxItems(
|
||||
location: Constants.MessageLocationType,
|
||||
labelId: String?,
|
||||
includeLabels: Boolean,
|
||||
uuid: String,
|
||||
refreshMessages: Boolean
|
||||
): LiveData<MailboxState> {
|
||||
if (conversationModeEnabled(location)) {
|
||||
return conversationsAsMailboxItems(location, labelId)
|
||||
}
|
||||
) {
|
||||
|
||||
fetchMessages(
|
||||
null,
|
||||
location,
|
||||
labelId,
|
||||
includeLabels,
|
||||
uuid,
|
||||
refreshMessages
|
||||
)
|
||||
|
||||
return getMessagesByLocation(location, labelId).switchMap {
|
||||
liveData { emit(MailboxState(messagesToMailboxItems(it))) }
|
||||
}
|
||||
mailboxLocation
|
||||
.onEach { location ->
|
||||
// refresh messages
|
||||
if (!conversationModeEnabled(location)) {
|
||||
fetchMessages(
|
||||
null,
|
||||
location,
|
||||
labelId,
|
||||
includeLabels,
|
||||
uuid,
|
||||
refreshMessages
|
||||
)
|
||||
}
|
||||
}
|
||||
.flatMapLatest { location ->
|
||||
if (conversationModeEnabled(location)) {
|
||||
conversationsAsMailboxItems(location, labelId)
|
||||
.onEach {
|
||||
_mailboxState.value = it
|
||||
}
|
||||
} else {
|
||||
getMessagesByLocation(location, labelId)
|
||||
.asFlow()
|
||||
.map {
|
||||
messagesToMailboxItems(it)
|
||||
}
|
||||
.onEach {
|
||||
_mailboxState.value = MailboxState.Data(
|
||||
it,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.catch {
|
||||
_mailboxState.value = MailboxState.Error(
|
||||
"Failed getting messages",
|
||||
it
|
||||
)
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
fun loadMailboxItems(
|
||||
location: Constants.MessageLocationType,
|
||||
labelId: String?,
|
||||
includeLabels: Boolean,
|
||||
uuid: String,
|
||||
refreshMessages: Boolean,
|
||||
oldestItemTimestamp: Long
|
||||
) {
|
||||
|
||||
val location = mailboxLocation.value
|
||||
if (conversationModeEnabled(location)) {
|
||||
val userId = userManager.currentUserId ?: return
|
||||
val locationId = labelId ?: location.messageLocationTypeValue.toString()
|
||||
|
@ -330,27 +370,27 @@ class MailboxViewModel @Inject constructor(
|
|||
private fun conversationsAsMailboxItems(
|
||||
location: Constants.MessageLocationType,
|
||||
labelId: String?
|
||||
): LiveData<MailboxState> {
|
||||
val userId = userManager.currentUserId ?: return MutableLiveData(MailboxState(noMoreItems = true))
|
||||
): Flow<MailboxState> {
|
||||
val userId = userManager.currentUserId ?: return flowOf(MailboxState.Data(noMoreItems = true))
|
||||
val locationId = labelId ?: location.messageLocationTypeValue.toString()
|
||||
return getConversations(
|
||||
userId, locationId
|
||||
).map { result ->
|
||||
when (result) {
|
||||
is GetConversationsResult.Success -> {
|
||||
return@map MailboxState(
|
||||
MailboxState.Data(
|
||||
conversationsToMailboxItems(result.conversations, locationId)
|
||||
)
|
||||
}
|
||||
is GetConversationsResult.NoConversationsFound -> {
|
||||
return@map MailboxState(noMoreItems = true)
|
||||
MailboxState.Data(noMoreItems = true)
|
||||
}
|
||||
is GetConversationsResult.Error -> {
|
||||
Timber.e(result.throwable, "Failed getting conversations")
|
||||
return@map MailboxState(error = "Failed getting conversations")
|
||||
MailboxState.Error(error = "Failed getting conversations", result.throwable)
|
||||
}
|
||||
}
|
||||
}.asLiveData()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun conversationsToMailboxItems(
|
||||
|
@ -573,5 +613,9 @@ class MailboxViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun setNewMailboxLocation(newLocation: Constants.MessageLocationType) {
|
||||
_mailboxLocation.value = newLocation
|
||||
}
|
||||
|
||||
data class MaxLabelsReached(val subject: String?, val maxAllowedLabels: Int)
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ import ch.protonmail.android.domain.entity.Id
|
|||
import ch.protonmail.android.domain.entity.Name
|
||||
import ch.protonmail.android.jobs.FetchByLocationJob
|
||||
import ch.protonmail.android.jobs.FetchMessageCountsJob
|
||||
import ch.protonmail.android.mailbox.domain.ChangeConversationsReadStatus
|
||||
import ch.protonmail.android.mailbox.domain.Conversation
|
||||
import ch.protonmail.android.mailbox.domain.GetConversations
|
||||
import ch.protonmail.android.mailbox.domain.GetConversationsResult
|
||||
import ch.protonmail.android.mailbox.domain.ChangeConversationsReadStatus
|
||||
import ch.protonmail.android.mailbox.domain.model.Correspondent
|
||||
import ch.protonmail.android.mailbox.domain.model.LabelContext
|
||||
import ch.protonmail.android.mailbox.presentation.ConversationModeEnabled
|
||||
|
@ -55,7 +55,6 @@ import ch.protonmail.android.mailbox.presentation.MailboxState
|
|||
import ch.protonmail.android.mailbox.presentation.MailboxViewModel
|
||||
import ch.protonmail.android.mailbox.presentation.model.MailboxUiItem
|
||||
import ch.protonmail.android.mailbox.presentation.model.MessageData
|
||||
import ch.protonmail.android.testAndroid.lifecycle.testObserver
|
||||
import ch.protonmail.android.ui.view.LabelChipUiModel
|
||||
import ch.protonmail.android.usecase.VerifyConnection
|
||||
import ch.protonmail.android.usecase.delete.DeleteMessage
|
||||
|
@ -202,7 +201,7 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
false,
|
||||
"",
|
||||
false
|
||||
).testObserver()
|
||||
)
|
||||
|
||||
// Then
|
||||
val expected = MailboxUiItem(
|
||||
|
@ -525,7 +524,6 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
every { userManager.currentUserId } returns userId
|
||||
|
||||
viewModel.loadMailboxItems(
|
||||
location,
|
||||
labelId,
|
||||
includeLabels,
|
||||
uuid,
|
||||
|
@ -550,7 +548,6 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
every { userManager.currentUserId } returns userId
|
||||
|
||||
viewModel.loadMailboxItems(
|
||||
location,
|
||||
labelId,
|
||||
includeLabels,
|
||||
uuid,
|
||||
|
@ -577,7 +574,6 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
every { userManager.currentUserId } returns userId
|
||||
|
||||
viewModel.loadMailboxItems(
|
||||
ARCHIVE,
|
||||
null,
|
||||
false,
|
||||
"9238423bbe2h3283742h3hh2bjsd",
|
||||
|
@ -600,7 +596,6 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
every { conversationModeEnabled(location) } returns true
|
||||
|
||||
viewModel.loadMailboxItems(
|
||||
location,
|
||||
labelId,
|
||||
false,
|
||||
uuid,
|
||||
|
@ -1006,7 +1001,7 @@ class MailboxViewModelTest : CoroutinesTest {
|
|||
val location = LABEL
|
||||
val labelId = "labelId923844"
|
||||
every { conversationModeEnabled(location) } returns true
|
||||
coEvery { getConversations(currentUserId, labelId) } returns flowOf(GetConversationsResult.Error)
|
||||
coEvery { getConversations(currentUserId, labelId) } returns flowOf(GetConversationsResult.Error())
|
||||
|
||||
val actual = viewModel.getMailboxItems(
|
||||
location,
|
||||
|
|
|
@ -90,7 +90,7 @@ class GetConversationsTest : CoroutinesTest {
|
|||
|
||||
val actual = getConversations.invoke(userId, MessageLocationType.INBOX.messageLocationTypeValue.toString())
|
||||
|
||||
val error = GetConversationsResult.Error
|
||||
val error = GetConversationsResult.Error()
|
||||
assertEquals(error, actual.first())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue