forked from github/wulkanowy-mirror
Add deleting messages (#290)
This commit is contained in:
parent
f2855d598d
commit
2bff468e56
@ -58,4 +58,8 @@ class MessageRemote @Inject constructor(private val api: Api) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun deleteMessage(message: Message): Single<Boolean> {
|
||||
return api.deleteMessages(listOf(Pair(message.realId, message.folderId)))
|
||||
}
|
||||
}
|
||||
|
@ -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<Boolean> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -30,7 +30,7 @@ class SendMessagePresenter @Inject constructor(
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<SendMessageView>(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<Recipient> = emptyList()
|
||||
var selectedRecipient: List<Recipient> = 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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
10
app/src/main/res/drawable/ic_message_delete_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_message_delete_24dp.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
|
||||
</vector>
|
@ -10,6 +10,7 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/messagePreviewContentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
|
@ -13,4 +13,10 @@
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/message_forward"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/messagePreviewMenuDelete"
|
||||
android:icon="@drawable/ic_message_delete_24dp"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/message_delete"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
|
@ -141,6 +141,10 @@
|
||||
<string name="message_date">Data: %s</string>
|
||||
<string name="message_reply">Odpowiedz</string>
|
||||
<string name="message_forward">Prześlij dalej</string>
|
||||
<string name="message_delete">Usuń</string>
|
||||
<string name="message_move_to_bin">Przenieś do kosza</string>
|
||||
<string name="message_delete_forever">Usuń trwale</string>
|
||||
<string name="message_delete_success">Wiadomość usunięta pomyślnie</string>
|
||||
<string name="message_subject">Temat</string>
|
||||
<string name="message_content">Treść</string>
|
||||
<string name="message_send_successful">Wiadomość wysłana pomyślnie</string>
|
||||
|
@ -135,6 +135,10 @@
|
||||
<string name="message_date">Date: %s</string>
|
||||
<string name="message_reply">Reply</string>
|
||||
<string name="message_forward">Forward</string>
|
||||
<string name="message_delete">Delete</string>
|
||||
<string name="message_move_to_bin">Move to trash</string>
|
||||
<string name="message_delete_forever">Delete permanently</string>
|
||||
<string name="message_delete_success">Message deleted successfully</string>
|
||||
<string name="message_subject">Subject</string>
|
||||
<string name="message_content">Content</string>
|
||||
<string name="message_send_successful">Message sent successfully</string>
|
||||
|
Loading…
Reference in New Issue
Block a user