proton-mail-android/app/src/main/java/ch/protonmail/android/adapters/messages/MessagesRecyclerViewAdapter.kt

233 lines
8.4 KiB
Kotlin
Raw Normal View History

2020-04-16 15:44:53 +00:00
/*
* Copyright (c) 2020 Proton Technologies AG
Replace imports for import ch.protonmail.android.api.models.room..+; MAILAND-1189 # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/ContactGroupsDatabaseTest.kt # app/src/main/java/ch/protonmail/android/api/segments/contact/ContactEmailsManager.kt # app/src/main/java/ch/protonmail/android/api/segments/event/EventHandler.kt # app/src/main/java/ch/protonmail/android/contacts/groups/details/ContactGroupDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsFragment.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsRepository.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/list/listView/ProtonMailContactsLiveData.kt # app/src/main/java/ch/protonmail/android/jobs/UpdateContactJob.java # app/src/test/java/ch/protonmail/android/contacts/details/ContactDetailsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/details/ContactGroupsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/ContactGroupsViewModelTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/edit/ContactGroupEditCreateRepositoryTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/activities/messageDetails/viewmodel/MessageDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/api/models/messages/receive/ServerAttachment.kt # app/src/main/java/ch/protonmail/android/attachments/DownloadEmbeddedAttachmentsWorker.kt # app/src/main/java/ch/protonmail/android/jobs/helper/EmbeddedImage.kt # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/contacts/ContactDaoTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/api/models/factories/PackageFactory.java # app/src/main/java/ch/protonmail/android/api/models/factories/SendPreferencesFactory.java # app/src/main/java/ch/protonmail/android/attachments/UploadAttachments.kt # app/src/main/java/ch/protonmail/android/compose/ComposeMessageViewModel.kt # app/src/main/java/ch/protonmail/android/core/ProtonMailApplication.java # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # app/src/main/java/ch/protonmail/android/usecase/compose/SaveDraft.kt # app/src/test/java/ch/protonmail/android/attachments/UploadAttachmentsTest.kt # app/src/test/java/ch/protonmail/android/compose/ComposeMessageViewModelTest.kt # app/src/test/java/ch/protonmail/android/usecase/compose/SaveDraftTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/di/ApplicationModule.kt # app/src/main/java/ch/protonmail/android/fcm/FcmIntentService.java
2021-03-18 09:46:25 +00:00
*
2020-04-16 15:44:53 +00:00
* This file is part of ProtonMail.
Replace imports for import ch.protonmail.android.api.models.room..+; MAILAND-1189 # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/ContactGroupsDatabaseTest.kt # app/src/main/java/ch/protonmail/android/api/segments/contact/ContactEmailsManager.kt # app/src/main/java/ch/protonmail/android/api/segments/event/EventHandler.kt # app/src/main/java/ch/protonmail/android/contacts/groups/details/ContactGroupDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsFragment.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsRepository.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/list/listView/ProtonMailContactsLiveData.kt # app/src/main/java/ch/protonmail/android/jobs/UpdateContactJob.java # app/src/test/java/ch/protonmail/android/contacts/details/ContactDetailsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/details/ContactGroupsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/ContactGroupsViewModelTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/edit/ContactGroupEditCreateRepositoryTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/activities/messageDetails/viewmodel/MessageDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/api/models/messages/receive/ServerAttachment.kt # app/src/main/java/ch/protonmail/android/attachments/DownloadEmbeddedAttachmentsWorker.kt # app/src/main/java/ch/protonmail/android/jobs/helper/EmbeddedImage.kt # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/contacts/ContactDaoTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/api/models/factories/PackageFactory.java # app/src/main/java/ch/protonmail/android/api/models/factories/SendPreferencesFactory.java # app/src/main/java/ch/protonmail/android/attachments/UploadAttachments.kt # app/src/main/java/ch/protonmail/android/compose/ComposeMessageViewModel.kt # app/src/main/java/ch/protonmail/android/core/ProtonMailApplication.java # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # app/src/main/java/ch/protonmail/android/usecase/compose/SaveDraft.kt # app/src/test/java/ch/protonmail/android/attachments/UploadAttachmentsTest.kt # app/src/test/java/ch/protonmail/android/compose/ComposeMessageViewModelTest.kt # app/src/test/java/ch/protonmail/android/usecase/compose/SaveDraftTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/di/ApplicationModule.kt # app/src/main/java/ch/protonmail/android/fcm/FcmIntentService.java
2021-03-18 09:46:25 +00:00
*
2020-04-16 15:44:53 +00:00
* ProtonMail is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
Replace imports for import ch.protonmail.android.api.models.room..+; MAILAND-1189 # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/ContactGroupsDatabaseTest.kt # app/src/main/java/ch/protonmail/android/api/segments/contact/ContactEmailsManager.kt # app/src/main/java/ch/protonmail/android/api/segments/event/EventHandler.kt # app/src/main/java/ch/protonmail/android/contacts/groups/details/ContactGroupDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsFragment.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsRepository.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/list/listView/ProtonMailContactsLiveData.kt # app/src/main/java/ch/protonmail/android/jobs/UpdateContactJob.java # app/src/test/java/ch/protonmail/android/contacts/details/ContactDetailsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/details/ContactGroupsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/ContactGroupsViewModelTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/edit/ContactGroupEditCreateRepositoryTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/activities/messageDetails/viewmodel/MessageDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/api/models/messages/receive/ServerAttachment.kt # app/src/main/java/ch/protonmail/android/attachments/DownloadEmbeddedAttachmentsWorker.kt # app/src/main/java/ch/protonmail/android/jobs/helper/EmbeddedImage.kt # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/contacts/ContactDaoTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/api/models/factories/PackageFactory.java # app/src/main/java/ch/protonmail/android/api/models/factories/SendPreferencesFactory.java # app/src/main/java/ch/protonmail/android/attachments/UploadAttachments.kt # app/src/main/java/ch/protonmail/android/compose/ComposeMessageViewModel.kt # app/src/main/java/ch/protonmail/android/core/ProtonMailApplication.java # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # app/src/main/java/ch/protonmail/android/usecase/compose/SaveDraft.kt # app/src/test/java/ch/protonmail/android/attachments/UploadAttachmentsTest.kt # app/src/test/java/ch/protonmail/android/compose/ComposeMessageViewModelTest.kt # app/src/test/java/ch/protonmail/android/usecase/compose/SaveDraftTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/di/ApplicationModule.kt # app/src/main/java/ch/protonmail/android/fcm/FcmIntentService.java
2021-03-18 09:46:25 +00:00
*
2020-04-16 15:44:53 +00:00
* ProtonMail is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
Replace imports for import ch.protonmail.android.api.models.room..+; MAILAND-1189 # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/ContactGroupsDatabaseTest.kt # app/src/main/java/ch/protonmail/android/api/segments/contact/ContactEmailsManager.kt # app/src/main/java/ch/protonmail/android/api/segments/event/EventHandler.kt # app/src/main/java/ch/protonmail/android/contacts/groups/details/ContactGroupDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsFragment.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsRepository.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/list/listView/ProtonMailContactsLiveData.kt # app/src/main/java/ch/protonmail/android/jobs/UpdateContactJob.java # app/src/test/java/ch/protonmail/android/contacts/details/ContactDetailsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/details/ContactGroupsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/ContactGroupsViewModelTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/edit/ContactGroupEditCreateRepositoryTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/activities/messageDetails/viewmodel/MessageDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/api/models/messages/receive/ServerAttachment.kt # app/src/main/java/ch/protonmail/android/attachments/DownloadEmbeddedAttachmentsWorker.kt # app/src/main/java/ch/protonmail/android/jobs/helper/EmbeddedImage.kt # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/contacts/ContactDaoTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/api/models/factories/PackageFactory.java # app/src/main/java/ch/protonmail/android/api/models/factories/SendPreferencesFactory.java # app/src/main/java/ch/protonmail/android/attachments/UploadAttachments.kt # app/src/main/java/ch/protonmail/android/compose/ComposeMessageViewModel.kt # app/src/main/java/ch/protonmail/android/core/ProtonMailApplication.java # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # app/src/main/java/ch/protonmail/android/usecase/compose/SaveDraft.kt # app/src/test/java/ch/protonmail/android/attachments/UploadAttachmentsTest.kt # app/src/test/java/ch/protonmail/android/compose/ComposeMessageViewModelTest.kt # app/src/test/java/ch/protonmail/android/usecase/compose/SaveDraftTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/di/ApplicationModule.kt # app/src/main/java/ch/protonmail/android/fcm/FcmIntentService.java
2021-03-18 09:46:25 +00:00
*
2020-04-16 15:44:53 +00:00
* You should have received a copy of the GNU General Public License
* along with ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.adapters.messages
import android.content.Context
Replace imports for import ch.protonmail.android.api.models.room..+; MAILAND-1189 # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/ContactGroupsDatabaseTest.kt # app/src/main/java/ch/protonmail/android/api/segments/contact/ContactEmailsManager.kt # app/src/main/java/ch/protonmail/android/api/segments/event/EventHandler.kt # app/src/main/java/ch/protonmail/android/contacts/groups/details/ContactGroupDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsFragment.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsRepository.kt # app/src/main/java/ch/protonmail/android/contacts/groups/list/ContactGroupsViewModel.kt # app/src/main/java/ch/protonmail/android/contacts/list/listView/ProtonMailContactsLiveData.kt # app/src/main/java/ch/protonmail/android/jobs/UpdateContactJob.java # app/src/test/java/ch/protonmail/android/contacts/details/ContactDetailsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/details/ContactGroupsRepositoryTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/ContactGroupsViewModelTest.kt # app/src/test/java/ch/protonmail/android/contacts/groups/edit/ContactGroupEditCreateRepositoryTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/activities/messageDetails/viewmodel/MessageDetailsViewModel.kt # app/src/main/java/ch/protonmail/android/api/models/messages/receive/ServerAttachment.kt # app/src/main/java/ch/protonmail/android/attachments/DownloadEmbeddedAttachmentsWorker.kt # app/src/main/java/ch/protonmail/android/jobs/helper/EmbeddedImage.kt # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # Conflicts: # app/src/androidTest/java/ch/protonmail/android/api/models/room/contacts/ContactDaoTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/api/models/factories/PackageFactory.java # app/src/main/java/ch/protonmail/android/api/models/factories/SendPreferencesFactory.java # app/src/main/java/ch/protonmail/android/attachments/UploadAttachments.kt # app/src/main/java/ch/protonmail/android/compose/ComposeMessageViewModel.kt # app/src/main/java/ch/protonmail/android/core/ProtonMailApplication.java # app/src/main/java/ch/protonmail/android/jobs/messages/PostMessageJob.java # app/src/main/java/ch/protonmail/android/usecase/compose/SaveDraft.kt # app/src/test/java/ch/protonmail/android/attachments/UploadAttachmentsTest.kt # app/src/test/java/ch/protonmail/android/compose/ComposeMessageViewModelTest.kt # app/src/test/java/ch/protonmail/android/usecase/compose/SaveDraftTest.kt # Conflicts: # app/src/main/java/ch/protonmail/android/di/ApplicationModule.kt # app/src/main/java/ch/protonmail/android/fcm/FcmIntentService.java
2021-03-18 09:46:25 +00:00
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import ch.protonmail.android.api.models.room.contacts.ContactEmail
import ch.protonmail.android.api.models.room.messages.Label
import ch.protonmail.android.api.models.room.messages.Message
import ch.protonmail.android.api.models.room.pendingActions.PendingSend
import ch.protonmail.android.api.models.room.pendingActions.PendingUpload
2020-04-16 15:44:53 +00:00
import ch.protonmail.android.core.Constants
import ch.protonmail.android.data.local.model.ContactEmail
import ch.protonmail.android.data.local.model.Label
import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.data.local.model.PendingSend
import ch.protonmail.android.data.local.model.PendingUpload
2020-04-16 15:44:53 +00:00
import ch.protonmail.android.utils.ui.selection.SelectionModeEnum
import ch.protonmail.android.views.messagesList.MessagesListFooterView
import ch.protonmail.android.views.messagesList.MessagesListItemView
import kotlinx.android.synthetic.main.layout_sender_initial.view.*
import kotlinx.android.synthetic.main.list_item_mailbox.view.*
2020-04-16 15:44:53 +00:00
class MessagesRecyclerViewAdapter(
private val context: Context,
private val onSelectionModeChange: ((SelectionModeEnum) -> Unit)?
) : RecyclerView.Adapter<MessagesListViewHolder>() {
2020-04-16 15:44:53 +00:00
private var mMailboxLocation = Constants.MessageLocationType.INVALID
private var labels = mapOf<String, Label>()
private val messages = mutableListOf<Message>()
private val selectedMessageIds: MutableSet<String> = mutableSetOf()
private var pendingUploadList: List<PendingUpload>? = null
private var pendingSendList: List<PendingSend>? = null
private var contactsList: List<ContactEmail>? = null
private var onItemClick: ((Message) -> Unit)? = null
private var onItemSelectionChangedListener: (() -> Unit)? = null
2020-04-16 15:44:53 +00:00
var includeFooter: Boolean = false
set(value) {
if (field == value) {
return
}
field = value
if (value) {
notifyItemInserted(messages.size)
} else {
notifyItemRemoved(messages.size)
}
}
val checkedMessages get() = selectedMessageIds.mapNotNull { messages.find { message -> message.messageId == it } }
fun getItem(position: Int) = messages[position]
2020-04-16 15:44:53 +00:00
fun addAll(messages: List<Message>) {
this.messages.addAll(
messages.filter {
!it.deleted
}
)
2020-04-16 15:44:53 +00:00
notifyDataSetChanged()
}
fun clear() {
messages.clear()
notifyDataSetChanged()
}
fun setItemClick(onItemClick: ((Message) -> Unit)?) {
this.onItemClick = onItemClick
}
fun setOnItemSelectionChangedListener(onItemSelectionChangedListener: () -> Unit) {
this.onItemSelectionChangedListener = onItemSelectionChangedListener
}
2020-04-16 15:44:53 +00:00
private enum class ElementType {
MESSAGE, FOOTER
}
override fun getItemViewType(position: Int): Int {
val itemViewType = if (position == messages.size) ElementType.FOOTER else ElementType.MESSAGE
return itemViewType.ordinal
2020-04-16 15:44:53 +00:00
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessagesListViewHolder {
return when (ElementType.values()[viewType]) {
ElementType.MESSAGE -> MessagesListViewHolder.MessageViewHolder(MessagesListItemView(context))
2020-04-16 15:44:53 +00:00
ElementType.FOOTER -> MessagesListViewHolder.FooterViewHolder(MessagesListFooterView(context))
}
}
override fun getItemCount(): Int = messages.size + if (includeFooter) 1 else 0
2020-04-16 15:44:53 +00:00
override fun onBindViewHolder(holder: MessagesListViewHolder, position: Int) {
when (ElementType.values()[getItemViewType(position)]) {
ElementType.MESSAGE -> {
(holder as MessagesListViewHolder.MessageViewHolder).bindMessage(position)
}
2020-04-16 15:44:53 +00:00
ElementType.FOOTER -> {
// NOOP
2020-04-16 15:44:53 +00:00
}
}
}
private fun selectMessage(messageId: String, position: Int) {
if (selectedMessageIds.isEmpty()) {
onSelectionModeChange?.invoke(SelectionModeEnum.STARTED)
notifyDataSetChanged()
}
selectedMessageIds.add(messageId)
onItemSelectionChangedListener?.invoke()
notifyItemChanged(position)
}
private fun deselectMessage(messageId: String, position: Int) {
selectedMessageIds.remove(messageId)
if (selectedMessageIds.isEmpty()) {
onSelectionModeChange?.invoke(SelectionModeEnum.ENDED)
notifyDataSetChanged()
} else {
onItemSelectionChangedListener?.invoke()
notifyItemChanged(position)
}
}
private fun selectOrDeselectMessage(messageId: String, position: Int): Boolean {
if (onSelectionModeChange == null || onItemSelectionChangedListener == null) {
return false
}
if (selectedMessageIds.contains(messageId)) {
deselectMessage(messageId, position)
} else {
selectMessage(messageId, position)
}
return true
}
2020-04-16 15:44:53 +00:00
private fun MessagesListViewHolder.MessageViewHolder.bindMessage(position: Int) {
val message = messages[position]
val messageLabels = message.allLabelIDs.mapNotNull { labels[it] }
val pendingSend = pendingSendList?.find { it.messageId == message.messageId }
// under these conditions the message is in sending process
message.isBeingSent = pendingSend != null && pendingSend.sent == null
message.isAttachmentsBeingUploaded = pendingUploadList?.find { it.messageId == message.messageId } != null
message.senderDisplayName = contactsList?.find { message.senderEmail == it.email }?.name
?: message.senderName
2020-04-16 15:44:53 +00:00
this.view.bind(message, messageLabels, selectedMessageIds.isNotEmpty(), mMailboxLocation)
2020-04-16 15:44:53 +00:00
val isSelected = selectedMessageIds.contains(message.messageId)
this.view.checkImageView.isActivated = isSelected
2020-04-16 15:44:53 +00:00
this.view.tag = message.messageId
this.view.senderInitialView.tag = message.messageId
2020-04-16 15:44:53 +00:00
this.view.senderInitialView.setOnClickListener {
2020-04-16 15:44:53 +00:00
val messageId = it.tag as String
selectOrDeselectMessage(messageId, position)
}
this.view.setOnClickListener {
2020-04-16 15:44:53 +00:00
if (selectedMessageIds.isNotEmpty()) {
val messageId = it.tag as String
selectOrDeselectMessage(messageId, position)
2020-04-16 15:44:53 +00:00
} else {
onItemClick?.invoke(message)
}
}
this.view.setOnLongClickListener {
if (selectedMessageIds.isEmpty()) {
val messageId = it.tag as String
return@setOnLongClickListener selectOrDeselectMessage(messageId, position)
}
return@setOnLongClickListener true
}
}
2020-04-16 15:44:53 +00:00
fun endSelectionMode() {
selectedMessageIds.clear()
notifyDataSetChanged()
}
fun setLabels(labels: List<Label>) {
this.labels = labels.map { it.id to it }.toMap()
notifyDataSetChanged()
}
fun setPendingUploadsList(pendingUploadList: List<PendingUpload>) {
this.pendingUploadList = pendingUploadList
notifyDataSetChanged()
2020-04-16 15:44:53 +00:00
}
fun setPendingForSendingList(pendingSendList: List<PendingSend>) {
this.pendingSendList = pendingSendList
notifyDataSetChanged()
2020-04-16 15:44:53 +00:00
}
fun setContactsList(contactsList: List<ContactEmail>?) {
this.contactsList = contactsList
notifyDataSetChanged()
2020-04-16 15:44:53 +00:00
}
fun setNewLocation(mailboxLocation: Constants.MessageLocationType) {
mMailboxLocation = mailboxLocation
}
}