diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt index 3fb01d30..e9cff4ab 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt @@ -58,4 +58,8 @@ class MessageRemote @Inject constructor(private val api: Api) { } ) } + + fun deleteMessage(message: Message): Single { + return api.deleteMessages(listOf(Pair(message.realId, message.folderId))) + } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt index d319689e..09f19815 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt @@ -9,6 +9,7 @@ import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED import io.reactivex.Completable +import io.reactivex.Maybe import io.reactivex.Single import java.net.UnknownHostException import javax.inject.Inject @@ -89,4 +90,20 @@ class MessageRepository @Inject constructor( else Single.error(UnknownHostException()) } } + + fun deleteMessage(message: Message): Maybe { + return ReactiveNetwork.checkInternetConnectivity(settings) + .flatMap { + if (it) remote.deleteMessage(message) + else Single.error(UnknownHostException()) + } + .filter { it } + .doOnSuccess { + if (!message.removed) local.updateMessages(listOf(message.copy(removed = true).apply { + id = message.id + content = message.content + })) + else local.deleteMessages(listOf(message)) + } + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt index d8a6bc84..7bd35f2d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt @@ -7,6 +7,7 @@ import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.view.ViewGroup import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED @@ -75,12 +76,20 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView { messageProgress.visibility = if (show) VISIBLE else INVISIBLE } + fun onDeleteMessage(message: Message) { + presenter.onDeleteMessage(message) + } + fun onChildFragmentLoaded() { presenter.onChildViewLoaded() } + override fun notifyChildMessageDeleted(tabId: Int) { + (pagerAdapter.getFragmentInstance(tabId) as? MessageTabFragment)?.onParentDeleteMessage() + } + override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) { - (pagerAdapter.getFragmentInstance(index) as? MessageView.MessageChildView)?.onParentLoadData(forceRefresh) + (pagerAdapter.getFragmentInstance(index) as? MessageTabFragment)?.onParentLoadData(forceRefresh) } override fun openSendMessage() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt index 332d5b74..8e7af512 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.message +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.SchedulersProvider @@ -43,6 +44,15 @@ class MessagePresenter @Inject constructor( } } + fun onDeleteMessage(message: Message) { + view?.notifyChildMessageDeleted( + when (message.removed) { + true -> 2 + else -> message.folderId - 1 + } + ) + } + fun onSendMessageButtonClicked() { view?.openSendMessage() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt index 41257ecc..2aa4d78e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt @@ -14,10 +14,7 @@ interface MessageView : BaseView { fun notifyChildLoadData(index: Int, forceRefresh: Boolean) + fun notifyChildMessageDeleted(tabId: Int) + fun openSendMessage() - - interface MessageChildView { - - fun onParentLoadData(forceRefresh: Boolean) - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt index 9afb744f..4a752401 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt @@ -13,7 +13,9 @@ import android.view.ViewGroup import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.ui.base.session.BaseSessionFragment +import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import kotlinx.android.synthetic.main.fragment_message_preview.* import javax.inject.Inject @@ -26,6 +28,7 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi private var menuReplyButton: MenuItem? = null private var menuForwardButton: MenuItem? = null + private var menuDeleteButton: MenuItem? = null override val titleStringId: Int get() = R.string.message_title @@ -33,6 +36,9 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi override val noSubjectString: String get() = getString(R.string.message_no_subject) + override val deleteMessageSuccessString: String + get() = getString(R.string.message_delete_success) + companion object { const val MESSAGE_ID_KEY = "message_id" @@ -62,6 +68,7 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi inflater?.inflate(R.menu.action_menu_message_preview, menu) menuReplyButton = menu?.findItem(R.id.messagePreviewMenuReply) menuForwardButton = menu?.findItem(R.id.messagePreviewMenuForward) + menuDeleteButton = menu?.findItem(R.id.messagePreviewMenuDelete) presenter.onCreateOptionsMenu() } @@ -69,6 +76,7 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi return when (item?.itemId) { R.id.messagePreviewMenuReply -> presenter.onReply() R.id.messagePreviewMenuForward -> presenter.onForward() + R.id.messagePreviewMenuDelete -> presenter.onMessageDelete() else -> false } } @@ -97,9 +105,22 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi messagePreviewProgress.visibility = if (show) VISIBLE else GONE } + override fun showContent(show: Boolean) { + messagePreviewContentContainer.visibility = if (show) VISIBLE else GONE + } + override fun showOptions(show: Boolean) { menuReplyButton?.isVisible = show menuForwardButton?.isVisible = show + menuDeleteButton?.isVisible = show + } + + override fun setDeletedOptionsLabels() { + menuDeleteButton?.setTitle(R.string.message_delete_forever) + } + + override fun setNotDeletedOptionsLabels() { + menuDeleteButton?.setTitle(R.string.message_move_to_bin) } override fun showMessageError() { @@ -114,6 +135,14 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message)) } } + override fun popView() { + (activity as MainActivity).popView() + } + + override fun notifyParentMessageDeleted(message: Message) { + fragmentManager?.fragments?.forEach { if (it is MessageFragment) it.onDeleteMessage(message) } + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putInt(MESSAGE_ID_KEY, presenter.messageId) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt index 534c7ad3..397e103b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt @@ -47,7 +47,7 @@ class MessagePreviewPresenter @Inject constructor( setSubject(if (it.subject.isNotBlank()) it.subject else noSubjectString) setDate(it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")) setContent(it.content.orEmpty()) - showOptions(true) + initOptions() if (it.recipient.isNotBlank()) setRecipient(it.recipient) else setSender(it.sender) @@ -76,7 +76,56 @@ class MessagePreviewPresenter @Inject constructor( } else false } + private fun deleteMessage() { + message?.let { message -> + disposable.add(messageRepository.deleteMessage(message) + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .doOnSubscribe { + view?.run { + showContent(false) + showProgress(true) + showOptions(false) + } + } + .doFinally { + view?.showProgress(false) + } + .subscribe({ + view?.run { + notifyParentMessageDeleted(message) + showMessage(deleteMessageSuccessString) + popView() + } + }, { error -> + view?.showMessageError() + errorHandler.dispatch(error) + }, { + view?.showMessageError() + }) + ) + } + } + + fun onMessageDelete(): Boolean { + deleteMessage() + return true + } + + private fun initOptions() { + view?.apply { + showOptions(message != null) + message?.let { + when (it.removed) { + true -> setDeletedOptionsLabels() + false -> setNotDeletedOptionsLabels() + } + } + + } + } + fun onCreateOptionsMenu() { - view?.showOptions(message != null) + initOptions() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt index 3ff73396..8bc528a3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt @@ -7,6 +7,8 @@ interface MessagePreviewView : BaseSessionView { val noSubjectString: String + val deleteMessageSuccessString: String + fun setSubject(subject: String) fun setRecipient(recipient: String) @@ -19,11 +21,21 @@ interface MessagePreviewView : BaseSessionView { fun showProgress(show: Boolean) + fun showContent(show: Boolean) + fun showOptions(show: Boolean) + fun setDeletedOptionsLabels() + + fun setNotDeletedOptionsLabels() + fun showMessageError() fun openMessageReply(message: Message?) fun openMessageForward(message: Message?) + + fun popView() + + fun notifyParentMessageDeleted(message: Message) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt index 6ac7e226..3a44ea86 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt @@ -62,7 +62,7 @@ class SendMessageActivity : BaseActivity(), SendMessageView { supportActionBar?.setDisplayHomeAsUpEnabled(true) messageContainer = sendMessageContainer - presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as Boolean) + presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt index f57848d6..32e3d5b2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt @@ -30,7 +30,7 @@ class SendMessagePresenter @Inject constructor( private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler) { - fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean) { + fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) { super.onAttachView(view) Timber.i("Send message view is attached") loadData(message, reply) @@ -38,13 +38,13 @@ class SendMessagePresenter @Inject constructor( message?.let { setSubject(when (reply) { true -> "RE: " - false -> "FE: " + else -> "FW: " } + message.subject) - if (preferencesRepository.fillMessageContent || !reply) { + if (preferencesRepository.fillMessageContent || reply != true) { setContent( when (reply) { true -> "\n\n" - false -> "" + else -> "" } + when (message.sender.isNotEmpty()) { true -> "Od: ${message.sender}\n" false -> "Do: ${message.recipient}\n" @@ -59,7 +59,7 @@ class SendMessagePresenter @Inject constructor( return true } - private fun loadData(message: Message?, reply: Boolean) { + private fun loadData(message: Message?, reply: Boolean?) { var reportingUnit: ReportingUnit? = null var recipients: List = emptyList() var selectedRecipient: List = emptyList() @@ -76,7 +76,7 @@ class SendMessagePresenter @Inject constructor( recipients = it } .flatMapCompletable { - if (message == null || !reply) Completable.complete() + if (message == null || reply != true) Completable.complete() else recipientRepository.getMessageRecipients(student, message) .doOnSuccess { Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", it.size) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt index 047f2a34..1f4595ae 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt @@ -17,13 +17,12 @@ import io.github.wulkanowy.ui.base.session.BaseSessionFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.message.MessageItem -import io.github.wulkanowy.ui.modules.message.MessageView import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_message_tab.* import javax.inject.Inject -class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.MessageChildView { +class MessageTabFragment : BaseSessionFragment(), MessageTabView { @Inject lateinit var presenter: MessageTabPresenter @@ -115,10 +114,14 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me (parentFragment as? MessageFragment)?.onChildFragmentLoaded() } - override fun onParentLoadData(forceRefresh: Boolean) { + fun onParentLoadData(forceRefresh: Boolean) { presenter.onParentViewLoadData(forceRefresh) } + fun onParentDeleteMessage() { + presenter.onDeleteMessage() + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(MessageTabFragment.MESSAGE_TAB_FOLDER_ID, presenter.folder.name) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt index 7d9fda0d..4a8415e8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt @@ -34,7 +34,29 @@ class MessageTabPresenter @Inject constructor( onParentViewLoadData(true) } + fun onDeleteMessage() { + loadData(false) + } + fun onParentViewLoadData(forceRefresh: Boolean) { + loadData(forceRefresh) + } + + fun onMessageItemSelected(item: AbstractFlexibleItem<*>) { + if (item is MessageItem) { + Timber.i("Select message ${item.message.realId} item") + view?.run { + openMessage(item.message.realId) + if (item.message.unread) { + item.message.unread = false + updateItem(item) + updateMessage(item.message) + } + } + } + } + + private fun loadData(forceRefresh: Boolean) { Timber.i("Loading $folder message data started") disposable.apply { clear() @@ -67,20 +89,6 @@ class MessageTabPresenter @Inject constructor( } } - fun onMessageItemSelected(item: AbstractFlexibleItem<*>) { - if (item is MessageItem) { - Timber.i("Select message ${item.message.realId} item") - view?.run { - openMessage(item.message.realId) - if (item.message.unread) { - item.message.unread = false - updateItem(item) - updateMessage(item.message) - } - } - } - } - private fun updateMessage(message: Message) { Timber.i("Attempt to update message ${message.realId}") disposable.add(messageRepository.updateMessage(message) diff --git a/app/src/main/res/drawable/ic_message_delete_24dp.xml b/app/src/main/res/drawable/ic_message_delete_24dp.xml new file mode 100644 index 00000000..3760de23 --- /dev/null +++ b/app/src/main/res/drawable/ic_message_delete_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_message_preview.xml b/app/src/main/res/layout/fragment_message_preview.xml index 7150c03a..962d94ac 100644 --- a/app/src/main/res/layout/fragment_message_preview.xml +++ b/app/src/main/res/layout/fragment_message_preview.xml @@ -10,6 +10,7 @@ android:layout_height="match_parent"> + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 16ec15ff..3caa356e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -141,6 +141,10 @@ Data: %s Odpowiedz Prześlij dalej + Usuń + Przenieś do kosza + Usuń trwale + Wiadomość usunięta pomyślnie Temat Treść Wiadomość wysłana pomyślnie diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 98bef391..6a56b441 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -135,6 +135,10 @@ Date: %s Reply Forward + Delete + Move to trash + Delete permanently + Message deleted successfully Subject Content Message sent successfully