Fix saving failed status to drafts (#2410)
* fix saving failed statuses to drafts * use coroutine delay instead of timer
This commit is contained in:
parent
3d2ae4dcbb
commit
59b627664f
1 changed files with 56 additions and 69 deletions
|
@ -30,13 +30,12 @@ import dagger.android.AndroidInjection
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.util.Timer
|
|
||||||
import java.util.TimerTask
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -58,8 +57,6 @@ class SendStatusService : Service(), Injectable {
|
||||||
private val statusesToSend = ConcurrentHashMap<Int, StatusToSend>()
|
private val statusesToSend = ConcurrentHashMap<Int, StatusToSend>()
|
||||||
private val sendCalls = ConcurrentHashMap<Int, Call<Status>>()
|
private val sendCalls = ConcurrentHashMap<Int, Call<Status>>()
|
||||||
|
|
||||||
private val timer = Timer()
|
|
||||||
|
|
||||||
private val notificationManager by lazy { getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
private val notificationManager by lazy { getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
@ -154,6 +151,7 @@ class SendStatusService : Service(), Injectable {
|
||||||
|
|
||||||
val callback = object : Callback<Status> {
|
val callback = object : Callback<Status> {
|
||||||
override fun onResponse(call: Call<Status>, response: Response<Status>) {
|
override fun onResponse(call: Call<Status>, response: Response<Status>) {
|
||||||
|
serviceScope.launch {
|
||||||
|
|
||||||
val scheduled = !statusToSend.scheduledAt.isNullOrEmpty()
|
val scheduled = !statusToSend.scheduledAt.isNullOrEmpty()
|
||||||
statusesToSend.remove(statusId)
|
statusesToSend.remove(statusId)
|
||||||
|
@ -161,10 +159,8 @@ class SendStatusService : Service(), Injectable {
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
// If the status was loaded from a draft, delete the draft and associated media files.
|
// If the status was loaded from a draft, delete the draft and associated media files.
|
||||||
if (statusToSend.draftId != 0) {
|
if (statusToSend.draftId != 0) {
|
||||||
serviceScope.launch {
|
|
||||||
draftHelper.deleteDraftAndAttachments(statusToSend.draftId)
|
draftHelper.deleteDraftAndAttachments(statusToSend.draftId)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (scheduled) {
|
if (scheduled) {
|
||||||
response.body()?.let(::StatusScheduledEvent)?.let(eventHub::dispatch)
|
response.body()?.let(::StatusScheduledEvent)?.let(eventHub::dispatch)
|
||||||
|
@ -181,29 +177,30 @@ class SendStatusService : Service(), Injectable {
|
||||||
.setSmallIcon(R.drawable.ic_notify)
|
.setSmallIcon(R.drawable.ic_notify)
|
||||||
.setContentTitle(getString(R.string.send_post_notification_error_title))
|
.setContentTitle(getString(R.string.send_post_notification_error_title))
|
||||||
.setContentText(getString(R.string.send_post_notification_saved_content))
|
.setContentText(getString(R.string.send_post_notification_saved_content))
|
||||||
.setColor(ContextCompat.getColor(this@SendStatusService, R.color.notification_color))
|
.setColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
this@SendStatusService,
|
||||||
|
R.color.notification_color
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
notificationManager.cancel(statusId)
|
notificationManager.cancel(statusId)
|
||||||
notificationManager.notify(errorNotificationId--, builder.build())
|
notificationManager.notify(errorNotificationId--, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
stopSelfWhenDone()
|
stopSelfWhenDone()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<Status>, t: Throwable) {
|
override fun onFailure(call: Call<Status>, t: Throwable) {
|
||||||
|
serviceScope.launch {
|
||||||
var backoff = TimeUnit.SECONDS.toMillis(statusToSend.retries.toLong())
|
var backoff = TimeUnit.SECONDS.toMillis(statusToSend.retries.toLong())
|
||||||
if (backoff > MAX_RETRY_INTERVAL) {
|
if (backoff > MAX_RETRY_INTERVAL) {
|
||||||
backoff = MAX_RETRY_INTERVAL
|
backoff = MAX_RETRY_INTERVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.schedule(
|
delay(backoff)
|
||||||
object : TimerTask() {
|
|
||||||
override fun run() {
|
|
||||||
sendStatus(statusId)
|
sendStatus(statusId)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
backoff
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +215,7 @@ class SendStatusService : Service(), Injectable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelSending(statusId: Int) {
|
private fun cancelSending(statusId: Int) = serviceScope.launch {
|
||||||
val statusToCancel = statusesToSend.remove(statusId)
|
val statusToCancel = statusesToSend.remove(statusId)
|
||||||
if (statusToCancel != null) {
|
if (statusToCancel != null) {
|
||||||
val sendCall = sendCalls.remove(statusId)
|
val sendCall = sendCalls.remove(statusId)
|
||||||
|
@ -230,24 +227,15 @@ class SendStatusService : Service(), Injectable {
|
||||||
.setSmallIcon(R.drawable.ic_notify)
|
.setSmallIcon(R.drawable.ic_notify)
|
||||||
.setContentTitle(getString(R.string.send_post_notification_cancel_title))
|
.setContentTitle(getString(R.string.send_post_notification_cancel_title))
|
||||||
.setContentText(getString(R.string.send_post_notification_saved_content))
|
.setContentText(getString(R.string.send_post_notification_saved_content))
|
||||||
.setColor(ContextCompat.getColor(this, R.color.notification_color))
|
.setColor(ContextCompat.getColor(this@SendStatusService, R.color.notification_color))
|
||||||
|
|
||||||
notificationManager.notify(statusId, builder.build())
|
notificationManager.notify(statusId, builder.build())
|
||||||
|
|
||||||
timer.schedule(
|
delay(5000)
|
||||||
object : TimerTask() {
|
|
||||||
override fun run() {
|
|
||||||
notificationManager.cancel(statusId)
|
|
||||||
stopSelfWhenDone()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
5000
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveStatusToDrafts(status: StatusToSend) {
|
private suspend fun saveStatusToDrafts(status: StatusToSend) {
|
||||||
serviceScope.launch {
|
|
||||||
draftHelper.saveDraft(
|
draftHelper.saveDraft(
|
||||||
draftId = status.draftId,
|
draftId = status.draftId,
|
||||||
accountId = status.accountId,
|
accountId = status.accountId,
|
||||||
|
@ -262,7 +250,6 @@ class SendStatusService : Service(), Injectable {
|
||||||
failedToSend = true
|
failedToSend = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun cancelSendingIntent(statusId: Int): PendingIntent {
|
private fun cancelSendingIntent(statusId: Int): PendingIntent {
|
||||||
val intent = Intent(this, SendStatusService::class.java)
|
val intent = Intent(this, SendStatusService::class.java)
|
||||||
|
|
Loading…
Reference in a new issue