MessageService.kt 3.39 KB
Newer Older
1 2 3 4 5
package chat.rocket.android.chatroom.service

import android.app.job.JobParameters
import android.app.job.JobService
import chat.rocket.android.server.domain.CurrentServerRepository
6
import chat.rocket.android.server.domain.MessagesRepository
7
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
8 9
import chat.rocket.common.RocketChatException
import chat.rocket.core.internal.rest.sendMessage
10
import chat.rocket.core.model.Message
11
import dagger.android.AndroidInjection
12 13
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.launch
14
import timber.log.Timber
15 16 17 18 19 20 21
import javax.inject.Inject

class MessageService : JobService() {
    @Inject
    lateinit var factory: ConnectionManagerFactory
    @Inject
    lateinit var currentServerRepository: CurrentServerRepository
22 23 24 25 26 27 28
    @Inject
    lateinit var messageRepository: MessagesRepository

    override fun onCreate() {
        super.onCreate()
        AndroidInjection.inject(this)
    }
29 30

    override fun onStopJob(params: JobParameters?): Boolean {
31
        return false
32 33 34 35 36 37
    }

    override fun onStartJob(params: JobParameters?): Boolean {
        launch(CommonPool) {
            val currentServer = currentServerRepository.get()
            if (currentServer != null) {
38 39
                retrySendingMessages(params, currentServer)
                jobFinished(params, false)
40 41 42 43
            }
        }
        return true
    }
44

45
    private suspend fun retrySendingMessages(params: JobParameters?, currentServer: String) {
46
        val temporaryMessages = messageRepository.getAllUnsent()
47
            .sortedWith(compareBy(Message::timestamp))
48 49 50 51
        if (temporaryMessages.isNotEmpty()) {
            val connectionManager = factory.create(currentServer)
            val client = connectionManager.client
            temporaryMessages.forEach { message ->
52 53 54 55 56 57 58 59 60 61
                try {
                    client.sendMessage(
                        message = message.message,
                        messageId = message.id,
                        roomId = message.roomId,
                        avatar = message.avatar,
                        attachments = message.attachments,
                        alias = message.senderAlias
                    )
                    messageRepository.save(message.copy(isTemporary = false))
62
                    Timber.d("Sent scheduled message given by id: ${message.id}")
63
                } catch (ex: Exception) {
64
                    Timber.e(ex)
65 66
                    // TODO - remove the generic message when we implement :userId:/message subscription
                    if (ex is IllegalStateException) {
67
                        Timber.e(ex, "Probably a read-only problem...")
68
                        // TODO: For now we are only going to reschedule when api is fixed.
69
                        messageRepository.removeById(message.id)
70 71 72 73 74 75 76 77
                        jobFinished(params, false)
                    } else {
                        // some other error
                        if (ex.message?.contains("E11000", true) == true) {
                            // XXX: Temporary solution. We need proper error codes from the api.
                            messageRepository.save(message.copy(isTemporary = false))
                        }
                        jobFinished(params, true)
78 79
                    }
                }
80 81 82 83 84 85 86
            }
        }
    }

    companion object {
        const val RETRY_SEND_MESSAGE_ID = 1
    }
87
}