forked from github/wulkanowy-mirror
Merge branch 'develop' into feature/attendance-excuse-whole-day
This commit is contained in:
commit
1591d494ab
@ -3,5 +3,10 @@ package io.github.wulkanowy.data.enums
|
|||||||
enum class MessageFolder(val id: Int = 1) {
|
enum class MessageFolder(val id: Int = 1) {
|
||||||
RECEIVED(1),
|
RECEIVED(1),
|
||||||
SENT(2),
|
SENT(2),
|
||||||
TRASHED(3)
|
TRASHED(3),
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun byId(id: Int) = entries.first { it.id == id }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import io.github.wulkanowy.data.db.entities.Recipient
|
|||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder
|
import io.github.wulkanowy.data.enums.MessageFolder
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||||
|
import io.github.wulkanowy.data.enums.MessageFolder.SENT
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
|
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
|
||||||
import io.github.wulkanowy.data.mappers.mapFromEntities
|
import io.github.wulkanowy.data.mappers.mapFromEntities
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
@ -25,6 +26,7 @@ import io.github.wulkanowy.data.networkBoundResource
|
|||||||
import io.github.wulkanowy.data.onResourceError
|
import io.github.wulkanowy.data.onResourceError
|
||||||
import io.github.wulkanowy.data.onResourceSuccess
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||||
|
import io.github.wulkanowy.data.toFirstResult
|
||||||
import io.github.wulkanowy.data.waitForResult
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
|
import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
@ -34,7 +36,6 @@ import io.github.wulkanowy.utils.getRefreshKey
|
|||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -155,17 +156,30 @@ class MessageRepository @Inject constructor(
|
|||||||
subject: String,
|
subject: String,
|
||||||
content: String,
|
content: String,
|
||||||
recipients: List<Recipient>,
|
recipients: List<Recipient>,
|
||||||
mailboxId: String,
|
mailbox: Mailbox,
|
||||||
) {
|
) {
|
||||||
sdk.init(student).sendMessage(
|
sdk.init(student).sendMessage(
|
||||||
subject = subject,
|
subject = subject,
|
||||||
content = content,
|
content = content,
|
||||||
recipients = recipients.mapFromEntities(),
|
recipients = recipients.mapFromEntities(),
|
||||||
mailboxId = mailboxId,
|
mailboxId = mailbox.globalKey,
|
||||||
)
|
)
|
||||||
|
refreshFolders(student, mailbox, listOf(SENT))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteMessages(student: Student, mailbox: Mailbox?, messages: List<Message>) {
|
suspend fun restoreMessages(student: Student, mailbox: Mailbox?, messages: List<Message>) {
|
||||||
|
sdk.init(student).restoreMessages(
|
||||||
|
messages = messages.map { it.messageGlobalKey },
|
||||||
|
)
|
||||||
|
|
||||||
|
refreshFolders(student, mailbox)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun deleteMessage(student: Student, message: Message) {
|
||||||
|
deleteMessages(student, listOf(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun deleteMessages(student: Student, messages: List<Message>) {
|
||||||
val firstMessage = messages.first()
|
val firstMessage = messages.first()
|
||||||
sdk.init(student).deleteMessages(
|
sdk.init(student).deleteMessages(
|
||||||
messages = messages.map { it.messageGlobalKey },
|
messages = messages.map { it.messageGlobalKey },
|
||||||
@ -184,18 +198,24 @@ class MessageRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
messagesDb.updateAll(deletedMessages)
|
messagesDb.updateAll(deletedMessages)
|
||||||
} else messagesDb.deleteAll(messages)
|
} else {
|
||||||
|
messagesDb.deleteAll(messages)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun refreshFolders(
|
||||||
|
student: Student,
|
||||||
|
mailbox: Mailbox?,
|
||||||
|
folders: List<MessageFolder> = MessageFolder.entries
|
||||||
|
) {
|
||||||
|
folders.forEach {
|
||||||
getMessages(
|
getMessages(
|
||||||
student = student,
|
student = student,
|
||||||
mailbox = mailbox,
|
mailbox = mailbox,
|
||||||
folder = TRASHED,
|
folder = it,
|
||||||
forceRefresh = true,
|
forceRefresh = true,
|
||||||
).first()
|
).toFirstResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteMessage(student: Student, mailbox: Mailbox?, message: Message) {
|
|
||||||
deleteMessages(student, mailbox, listOf(message))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getMailboxes(student: Student, forceRefresh: Boolean) = networkBoundResource(
|
suspend fun getMailboxes(student: Student, forceRefresh: Boolean) = networkBoundResource(
|
||||||
@ -240,7 +260,7 @@ class MessageRepository @Inject constructor(
|
|||||||
value?.let { json.encodeToString(it) }
|
value?.let { json.encodeToString(it) }
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun isMuted(author: String): Boolean {
|
private suspend fun isMuted(author: String): Boolean {
|
||||||
return mutedMessageSendersDao.checkMute(author)
|
return mutedMessageSendersDao.checkMute(author)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,12 @@ class MessagePreviewFragment :
|
|||||||
|
|
||||||
private var menuForwardButton: MenuItem? = null
|
private var menuForwardButton: MenuItem? = null
|
||||||
|
|
||||||
|
private var menuRestoreButton: MenuItem? = null
|
||||||
|
|
||||||
private var menuDeleteButton: MenuItem? = null
|
private var menuDeleteButton: MenuItem? = null
|
||||||
|
|
||||||
|
private var menuDeleteForeverButton: MenuItem? = null
|
||||||
|
|
||||||
private var menuShareButton: MenuItem? = null
|
private var menuShareButton: MenuItem? = null
|
||||||
|
|
||||||
private var menuPrintButton: MenuItem? = null
|
private var menuPrintButton: MenuItem? = null
|
||||||
@ -64,6 +68,9 @@ class MessagePreviewFragment :
|
|||||||
override val unmuteMessageSuccessString: String
|
override val unmuteMessageSuccessString: String
|
||||||
get() = getString(R.string.message_unmute_success)
|
get() = getString(R.string.message_unmute_success)
|
||||||
|
|
||||||
|
override val restoreMessageSuccessString: String
|
||||||
|
get() = getString(R.string.message_restore_success)
|
||||||
|
|
||||||
override val messageNoSubjectString: String
|
override val messageNoSubjectString: String
|
||||||
get() = getString(R.string.message_no_subject)
|
get() = getString(R.string.message_no_subject)
|
||||||
|
|
||||||
@ -111,7 +118,9 @@ class MessagePreviewFragment :
|
|||||||
inflater.inflate(R.menu.action_menu_message_preview, menu)
|
inflater.inflate(R.menu.action_menu_message_preview, menu)
|
||||||
menuReplyButton = menu.findItem(R.id.messagePreviewMenuReply)
|
menuReplyButton = menu.findItem(R.id.messagePreviewMenuReply)
|
||||||
menuForwardButton = menu.findItem(R.id.messagePreviewMenuForward)
|
menuForwardButton = menu.findItem(R.id.messagePreviewMenuForward)
|
||||||
|
menuRestoreButton = menu.findItem(R.id.messagePreviewMenuRestore)
|
||||||
menuDeleteButton = menu.findItem(R.id.messagePreviewMenuDelete)
|
menuDeleteButton = menu.findItem(R.id.messagePreviewMenuDelete)
|
||||||
|
menuDeleteForeverButton = menu.findItem(R.id.messagePreviewMenuDeleteForever)
|
||||||
menuShareButton = menu.findItem(R.id.messagePreviewMenuShare)
|
menuShareButton = menu.findItem(R.id.messagePreviewMenuShare)
|
||||||
menuPrintButton = menu.findItem(R.id.messagePreviewMenuPrint)
|
menuPrintButton = menu.findItem(R.id.messagePreviewMenuPrint)
|
||||||
menuMuteButton = menu.findItem(R.id.messagePreviewMenuMute)
|
menuMuteButton = menu.findItem(R.id.messagePreviewMenuMute)
|
||||||
@ -124,7 +133,9 @@ class MessagePreviewFragment :
|
|||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
R.id.messagePreviewMenuReply -> presenter.onReply()
|
R.id.messagePreviewMenuReply -> presenter.onReply()
|
||||||
R.id.messagePreviewMenuForward -> presenter.onForward()
|
R.id.messagePreviewMenuForward -> presenter.onForward()
|
||||||
|
R.id.messagePreviewMenuRestore -> presenter.onMessageRestore()
|
||||||
R.id.messagePreviewMenuDelete -> presenter.onMessageDelete()
|
R.id.messagePreviewMenuDelete -> presenter.onMessageDelete()
|
||||||
|
R.id.messagePreviewMenuDeleteForever -> presenter.onMessageDelete()
|
||||||
R.id.messagePreviewMenuShare -> presenter.onShare()
|
R.id.messagePreviewMenuShare -> presenter.onShare()
|
||||||
R.id.messagePreviewMenuPrint -> presenter.onPrint()
|
R.id.messagePreviewMenuPrint -> presenter.onPrint()
|
||||||
R.id.messagePreviewMenuMute -> presenter.onMute()
|
R.id.messagePreviewMenuMute -> presenter.onMute()
|
||||||
@ -152,23 +163,17 @@ class MessagePreviewFragment :
|
|||||||
binding.messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
|
binding.messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showOptions(show: Boolean, isReplayable: Boolean) {
|
override fun showOptions(show: Boolean, isReplayable: Boolean, isRestorable: Boolean) {
|
||||||
menuReplyButton?.isVisible = isReplayable
|
menuReplyButton?.isVisible = show && isReplayable
|
||||||
menuForwardButton?.isVisible = show
|
menuForwardButton?.isVisible = show
|
||||||
menuDeleteButton?.isVisible = show
|
menuRestoreButton?.isVisible = show && isRestorable
|
||||||
|
menuDeleteButton?.isVisible = show && !isRestorable
|
||||||
|
menuDeleteForeverButton?.isVisible = show && isRestorable
|
||||||
menuShareButton?.isVisible = show
|
menuShareButton?.isVisible = show
|
||||||
menuPrintButton?.isVisible = show
|
menuPrintButton?.isVisible = show
|
||||||
menuMuteButton?.isVisible = show && isReplayable
|
menuMuteButton?.isVisible = show && isReplayable
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setDeletedOptionsLabels() {
|
|
||||||
menuDeleteButton?.setTitle(R.string.message_delete_forever)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setNotDeletedOptionsLabels() {
|
|
||||||
menuDeleteButton?.setTitle(R.string.message_move_to_trash)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showErrorView(show: Boolean) {
|
override fun showErrorView(show: Boolean) {
|
||||||
binding.messagePreviewError.visibility = if (show) VISIBLE else GONE
|
binding.messagePreviewError.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,11 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
|||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class MessagePreviewPresenter @Inject constructor(
|
class MessagePreviewPresenter @Inject constructor(
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
@ -74,6 +76,7 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
delay(1.seconds)
|
||||||
view?.run {
|
view?.run {
|
||||||
showMessage(messageNotExists)
|
showMessage(messageNotExists)
|
||||||
popView()
|
popView()
|
||||||
@ -172,13 +175,51 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun restoreMessage() {
|
||||||
|
val message = messageWithAttachments?.message ?: return
|
||||||
|
|
||||||
|
view?.run {
|
||||||
|
showContent(false)
|
||||||
|
showProgress(true)
|
||||||
|
showOptions(
|
||||||
|
show = false,
|
||||||
|
isReplayable = false,
|
||||||
|
isRestorable = false,
|
||||||
|
)
|
||||||
|
showErrorView(false)
|
||||||
|
}
|
||||||
|
Timber.i("Restore message ${message.messageGlobalKey}")
|
||||||
|
presenterScope.launch {
|
||||||
|
runCatching {
|
||||||
|
val student = studentRepository.getCurrentStudent(decryptPass = true)
|
||||||
|
val mailbox = messageRepository.getMailboxByStudent(student)
|
||||||
|
messageRepository.restoreMessages(student, mailbox, listOfNotNull(message))
|
||||||
|
}
|
||||||
|
.onFailure {
|
||||||
|
retryCallback = { onMessageRestore() }
|
||||||
|
errorHandler.dispatch(it)
|
||||||
|
}
|
||||||
|
.onSuccess {
|
||||||
|
view?.run {
|
||||||
|
showMessage(restoreMessageSuccessString)
|
||||||
|
popView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view?.showProgress(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun deleteMessage() {
|
private fun deleteMessage() {
|
||||||
messageWithAttachments?.message ?: return
|
messageWithAttachments?.message ?: return
|
||||||
|
|
||||||
view?.run {
|
view?.run {
|
||||||
showContent(false)
|
showContent(false)
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showOptions(show = false, isReplayable = false)
|
showOptions(
|
||||||
|
show = false,
|
||||||
|
isReplayable = false,
|
||||||
|
isRestorable = false,
|
||||||
|
)
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +228,7 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
runCatching {
|
runCatching {
|
||||||
val student = studentRepository.getCurrentStudent(decryptPass = true)
|
val student = studentRepository.getCurrentStudent(decryptPass = true)
|
||||||
val mailbox = messageRepository.getMailboxByStudent(student)
|
messageRepository.deleteMessage(student, messageWithAttachments?.message!!)
|
||||||
messageRepository.deleteMessage(student, mailbox, messageWithAttachments?.message!!)
|
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
retryCallback = { onMessageDelete() }
|
retryCallback = { onMessageDelete() }
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
@ -213,6 +253,11 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onMessageRestore(): Boolean {
|
||||||
|
restoreMessage()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
fun onMessageDelete(): Boolean {
|
fun onMessageDelete(): Boolean {
|
||||||
deleteMessage()
|
deleteMessage()
|
||||||
return true
|
return true
|
||||||
@ -222,15 +267,9 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
showOptions(
|
showOptions(
|
||||||
show = messageWithAttachments?.message != null,
|
show = messageWithAttachments?.message != null,
|
||||||
isReplayable = messageWithAttachments?.message?.folderId != MessageFolder.SENT.id,
|
isReplayable = messageWithAttachments?.message?.folderId == MessageFolder.RECEIVED.id,
|
||||||
|
isRestorable = messageWithAttachments?.message?.folderId == MessageFolder.TRASHED.id,
|
||||||
)
|
)
|
||||||
messageWithAttachments?.message?.let {
|
|
||||||
when (it.folderId == MessageFolder.TRASHED.id) {
|
|
||||||
true -> setDeletedOptionsLabels()
|
|
||||||
false -> setNotDeletedOptionsLabels()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ interface MessagePreviewView : BaseView {
|
|||||||
|
|
||||||
val unmuteMessageSuccessString: String
|
val unmuteMessageSuccessString: String
|
||||||
|
|
||||||
|
val restoreMessageSuccessString: String
|
||||||
|
|
||||||
val messageNoSubjectString: String
|
val messageNoSubjectString: String
|
||||||
|
|
||||||
val printHTML: String
|
val printHTML: String
|
||||||
@ -35,11 +37,7 @@ interface MessagePreviewView : BaseView {
|
|||||||
|
|
||||||
fun setErrorRetryCallback(callback: () -> Unit)
|
fun setErrorRetryCallback(callback: () -> Unit)
|
||||||
|
|
||||||
fun showOptions(show: Boolean, isReplayable: Boolean)
|
fun showOptions(show: Boolean, isReplayable: Boolean, isRestorable: Boolean)
|
||||||
|
|
||||||
fun setDeletedOptionsLabels()
|
|
||||||
|
|
||||||
fun setNotDeletedOptionsLabels()
|
|
||||||
|
|
||||||
fun openMessageReply(message: Message?)
|
fun openMessageReply(message: Message?)
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
subject = subject,
|
subject = subject,
|
||||||
content = content,
|
content = content,
|
||||||
recipients = recipients,
|
recipients = recipients,
|
||||||
mailboxId = mailbox.globalKey,
|
mailbox = mailbox,
|
||||||
)
|
)
|
||||||
}.logResourceStatus("sending message").onEach {
|
}.logResourceStatus("sending message").onEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -5,7 +5,9 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.*
|
import android.view.View.GONE
|
||||||
|
import android.view.View.INVISIBLE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
@ -64,10 +66,12 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
if (presenter.folder == MessageFolder.TRASHED) {
|
val isTrashFolder = presenter.folder == MessageFolder.TRASHED
|
||||||
val menuItem = menu.findItem(R.id.messageTabContextMenuDelete)
|
|
||||||
menuItem.setTitle(R.string.message_delete_forever)
|
menu.findItem(R.id.messageTabContextMenuDelete).setVisible(!isTrashFolder)
|
||||||
}
|
menu.findItem(R.id.messageTabContextMenuDeleteForever).setVisible(isTrashFolder)
|
||||||
|
menu.findItem(R.id.messageTabContextMenuRestore).setVisible(isTrashFolder)
|
||||||
|
|
||||||
return presenter.onPrepareActionMode()
|
return presenter.onPrepareActionMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +83,8 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
|
|||||||
override fun onActionItemClicked(mode: ActionMode, menu: MenuItem): Boolean {
|
override fun onActionItemClicked(mode: ActionMode, menu: MenuItem): Boolean {
|
||||||
when (menu.itemId) {
|
when (menu.itemId) {
|
||||||
R.id.messageTabContextMenuDelete -> presenter.onActionModeSelectDelete()
|
R.id.messageTabContextMenuDelete -> presenter.onActionModeSelectDelete()
|
||||||
|
R.id.messageTabContextMenuRestore -> presenter.onActionModeSelectRestore()
|
||||||
|
R.id.messageTabContextMenuDeleteForever -> presenter.onActionModeSelectDelete()
|
||||||
R.id.messageTabContextMenuSelectAll -> presenter.onActionModeSelectCheckAll()
|
R.id.messageTabContextMenuSelectAll -> presenter.onActionModeSelectCheckAll()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -121,8 +121,27 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onActionModeSelectRestore() {
|
||||||
|
Timber.i("Restore ${messagesToDelete.size} messages")
|
||||||
|
val messageList = messagesToDelete.toList()
|
||||||
|
|
||||||
|
presenterScope.launch {
|
||||||
|
view?.run {
|
||||||
|
showProgress(true)
|
||||||
|
showContent(false)
|
||||||
|
showActionMode(false)
|
||||||
|
}
|
||||||
|
runCatching {
|
||||||
|
val student = studentRepository.getCurrentStudent(true)
|
||||||
|
messageRepository.restoreMessages(student, selectedMailbox, messageList)
|
||||||
|
}
|
||||||
|
.onFailure(errorHandler::dispatch)
|
||||||
|
.onSuccess { view?.showMessage(R.string.message_messages_restored) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun onActionModeSelectDelete() {
|
fun onActionModeSelectDelete() {
|
||||||
Timber.i("Delete ${messagesToDelete.size} messages)")
|
Timber.i("Delete ${messagesToDelete.size} messages")
|
||||||
val messageList = messagesToDelete.toList()
|
val messageList = messagesToDelete.toList()
|
||||||
|
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
@ -134,7 +153,7 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
|
|
||||||
runCatching {
|
runCatching {
|
||||||
val student = studentRepository.getCurrentStudent(true)
|
val student = studentRepository.getCurrentStudent(true)
|
||||||
messageRepository.deleteMessages(student, selectedMailbox, messageList)
|
messageRepository.deleteMessages(student, messageList)
|
||||||
}
|
}
|
||||||
.onFailure(errorHandler::dispatch)
|
.onFailure(errorHandler::dispatch)
|
||||||
.onSuccess { view?.showMessage(R.string.message_messages_deleted) }
|
.onSuccess { view?.showMessage(R.string.message_messages_deleted) }
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M14.12,10.47L12,12.59l-2.13,-2.12 -1.41,1.41L10.59,14l-2.12,2.12 1.41,1.41L12,15.41l2.12,2.12 1.41,-1.41L13.41,14l2.12,-2.12zM15.5,4l-1,-1h-5l-1,1H5v2h14V4zM6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM8,9h8v10H8V9z" />
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_menu_message_restore.xml
Normal file
9
app/src/main/res/drawable/ic_menu_message_restore.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4zM6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8,14L8,9h8v10L8,19v-5zM10,18h4v-4h2l-4,-4 -4,4h2z" />
|
||||||
|
</vector>
|
@ -29,6 +29,13 @@
|
|||||||
android:title="@string/message_forward"
|
android:title="@string/message_forward"
|
||||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/messagePreviewMenuRestore"
|
||||||
|
android:icon="@drawable/ic_menu_message_restore"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
android:title="@string/message_restore_from_trash"
|
||||||
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/messagePreviewMenuDelete"
|
android:id="@+id/messagePreviewMenuDelete"
|
||||||
android:icon="@drawable/ic_menu_message_delete"
|
android:icon="@drawable/ic_menu_message_delete"
|
||||||
@ -36,6 +43,13 @@
|
|||||||
android:title="@string/message_move_to_trash"
|
android:title="@string/message_move_to_trash"
|
||||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/messagePreviewMenuDeleteForever"
|
||||||
|
android:icon="@drawable/ic_menu_message_delete_forever"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
android:title="@string/message_delete_forever"
|
||||||
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/messagePreviewMenuMute"
|
android:id="@+id/messagePreviewMenuMute"
|
||||||
android:icon="@drawable/ic_settings_notifications"
|
android:icon="@drawable/ic_settings_notifications"
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/messageTabContextMenuRestore"
|
||||||
|
android:icon="@drawable/ic_menu_message_restore"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
android:title="@string/message_restore_from_trash"
|
||||||
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
|
app:showAsAction="always" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/messageTabContextMenuDelete"
|
android:id="@+id/messageTabContextMenuDelete"
|
||||||
android:icon="@drawable/ic_menu_message_delete"
|
android:icon="@drawable/ic_menu_message_delete"
|
||||||
@ -8,6 +15,13 @@
|
|||||||
android:title="@string/message_move_to_trash"
|
android:title="@string/message_move_to_trash"
|
||||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="always" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/messageTabContextMenuDeleteForever"
|
||||||
|
android:icon="@drawable/ic_menu_message_delete_forever"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
android:title="@string/message_delete_forever"
|
||||||
|
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||||
|
app:showAsAction="always" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/messageTabContextMenuSelectAll"
|
android:id="@+id/messageTabContextMenuSelectAll"
|
||||||
android:icon="@drawable/ic_message_select_all"
|
android:icon="@drawable/ic_message_select_all"
|
||||||
|
@ -327,8 +327,10 @@
|
|||||||
<string name="message_forward">Forward</string>
|
<string name="message_forward">Forward</string>
|
||||||
<string name="message_select_all">Select all</string>
|
<string name="message_select_all">Select all</string>
|
||||||
<string name="message_unselect_all">Unselect all</string>
|
<string name="message_unselect_all">Unselect all</string>
|
||||||
|
<string name="message_restore_from_trash">Restore from trash</string>
|
||||||
<string name="message_move_to_trash">Move to trash</string>
|
<string name="message_move_to_trash">Move to trash</string>
|
||||||
<string name="message_delete_forever">Delete permanently</string>
|
<string name="message_delete_forever">Delete permanently</string>
|
||||||
|
<string name="message_restore_success">Message restored successfully</string>
|
||||||
<string name="message_delete_success">Message deleted successfully</string>
|
<string name="message_delete_success">Message deleted successfully</string>
|
||||||
<string name="message_mailbox_type_student">student</string>
|
<string name="message_mailbox_type_student">student</string>
|
||||||
<string name="message_mailbox_type_parent">parent</string>
|
<string name="message_mailbox_type_parent">parent</string>
|
||||||
@ -366,6 +368,7 @@
|
|||||||
<item quantity="other">%1$d selected</item>
|
<item quantity="other">%1$d selected</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="message_messages_deleted">Messages deleted</string>
|
<string name="message_messages_deleted">Messages deleted</string>
|
||||||
|
<string name="message_messages_restored">Messages restored</string>
|
||||||
<string name="message_mailbox_chooser_title">Choose mailbox</string>
|
<string name="message_mailbox_chooser_title">Choose mailbox</string>
|
||||||
<string name="message_incognito_mode_on">Incognito mode is on</string>
|
<string name="message_incognito_mode_on">Incognito mode is on</string>
|
||||||
<string name="message_incognito_description">Thanks to incognito mode sender is not notified when you read the message</string>
|
<string name="message_incognito_description">Thanks to incognito mode sender is not notified when you read the message</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user