fix scheduling posts (#4392)
Mastodon returns different reponses when posting normally and when scheduling. This was previously ignored silently, but Moshi is more correct than Gson and fails, which causes the `SendStatusService` to retry sending forever and a lot of posts are scheduled. Mastodon should actually ignore multiple attempts at scheduling the same post, but doesn't so I filed this https://github.com/mastodon/mastodon/issues/30039 cc @cbeyls
This commit is contained in:
parent
f2ffba1679
commit
c55d79562c
|
@ -4,6 +4,7 @@ import com.keylesspalace.tusky.TabData
|
||||||
import com.keylesspalace.tusky.entity.Account
|
import com.keylesspalace.tusky.entity.Account
|
||||||
import com.keylesspalace.tusky.entity.Notification
|
import com.keylesspalace.tusky.entity.Notification
|
||||||
import com.keylesspalace.tusky.entity.Poll
|
import com.keylesspalace.tusky.entity.Poll
|
||||||
|
import com.keylesspalace.tusky.entity.ScheduledStatus
|
||||||
import com.keylesspalace.tusky.entity.Status
|
import com.keylesspalace.tusky.entity.Status
|
||||||
|
|
||||||
data class StatusChangedEvent(val status: Status) : Event
|
data class StatusChangedEvent(val status: Status) : Event
|
||||||
|
@ -13,7 +14,7 @@ data class BlockEvent(val accountId: String) : Event
|
||||||
data class MuteEvent(val accountId: String) : Event
|
data class MuteEvent(val accountId: String) : Event
|
||||||
data class StatusDeletedEvent(val statusId: String) : Event
|
data class StatusDeletedEvent(val statusId: String) : Event
|
||||||
data class StatusComposedEvent(val status: Status) : Event
|
data class StatusComposedEvent(val status: Status) : Event
|
||||||
data class StatusScheduledEvent(val status: Status) : Event
|
data class StatusScheduledEvent(val scheduledStatus: ScheduledStatus) : Event
|
||||||
data class ProfileEditedEvent(val newProfileData: Account) : Event
|
data class ProfileEditedEvent(val newProfileData: Account) : Event
|
||||||
data class PreferenceChangedEvent(val preferenceKey: String) : Event
|
data class PreferenceChangedEvent(val preferenceKey: String) : Event
|
||||||
data class MainTabsChangedEvent(val newTabs: List<TabData>) : Event
|
data class MainTabsChangedEvent(val newTabs: List<TabData>) : Event
|
||||||
|
|
|
@ -199,6 +199,14 @@ interface MastodonApi {
|
||||||
@Body status: NewStatus
|
@Body status: NewStatus
|
||||||
): NetworkResult<Status>
|
): NetworkResult<Status>
|
||||||
|
|
||||||
|
@POST("api/v1/statuses")
|
||||||
|
suspend fun createScheduledStatus(
|
||||||
|
@Header("Authorization") auth: String,
|
||||||
|
@Header(DOMAIN_HEADER) domain: String,
|
||||||
|
@Header("Idempotency-Key") idempotencyKey: String,
|
||||||
|
@Body status: NewStatus
|
||||||
|
): NetworkResult<ScheduledStatus>
|
||||||
|
|
||||||
@GET("api/v1/statuses/{id}")
|
@GET("api/v1/statuses/{id}")
|
||||||
suspend fun status(@Path("id") statusId: String): NetworkResult<Status>
|
suspend fun status(@Path("id") statusId: String): NetworkResult<Status>
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import com.keylesspalace.tusky.entity.Attachment
|
||||||
import com.keylesspalace.tusky.entity.MediaAttribute
|
import com.keylesspalace.tusky.entity.MediaAttribute
|
||||||
import com.keylesspalace.tusky.entity.NewPoll
|
import com.keylesspalace.tusky.entity.NewPoll
|
||||||
import com.keylesspalace.tusky.entity.NewStatus
|
import com.keylesspalace.tusky.entity.NewStatus
|
||||||
|
import com.keylesspalace.tusky.entity.ScheduledStatus
|
||||||
import com.keylesspalace.tusky.entity.Status
|
import com.keylesspalace.tusky.entity.Status
|
||||||
import com.keylesspalace.tusky.network.MastodonApi
|
import com.keylesspalace.tusky.network.MastodonApi
|
||||||
import com.keylesspalace.tusky.util.unsafeLazy
|
import com.keylesspalace.tusky.util.unsafeLazy
|
||||||
|
@ -256,13 +257,24 @@ class SendStatusService : Service(), Injectable {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val scheduled = !statusToSend.scheduledAt.isNullOrEmpty()
|
||||||
|
|
||||||
val sendResult = if (isNew) {
|
val sendResult = if (isNew) {
|
||||||
|
if (!scheduled) {
|
||||||
mastodonApi.createStatus(
|
mastodonApi.createStatus(
|
||||||
"Bearer " + account.accessToken,
|
"Bearer " + account.accessToken,
|
||||||
account.domain,
|
account.domain,
|
||||||
statusToSend.idempotencyKey,
|
statusToSend.idempotencyKey,
|
||||||
newStatus
|
newStatus
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
mastodonApi.createScheduledStatus(
|
||||||
|
"Bearer " + account.accessToken,
|
||||||
|
account.domain,
|
||||||
|
statusToSend.idempotencyKey,
|
||||||
|
newStatus
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mastodonApi.editStatus(
|
mastodonApi.editStatus(
|
||||||
statusToSend.statusId!!,
|
statusToSend.statusId!!,
|
||||||
|
@ -282,14 +294,12 @@ class SendStatusService : Service(), Injectable {
|
||||||
|
|
||||||
mediaUploader.cancelUploadScope(*statusToSend.media.map { it.localId }.toIntArray())
|
mediaUploader.cancelUploadScope(*statusToSend.media.map { it.localId }.toIntArray())
|
||||||
|
|
||||||
val scheduled = !statusToSend.scheduledAt.isNullOrEmpty()
|
|
||||||
|
|
||||||
if (scheduled) {
|
if (scheduled) {
|
||||||
eventHub.dispatch(StatusScheduledEvent(sentStatus))
|
eventHub.dispatch(StatusScheduledEvent(sentStatus as ScheduledStatus))
|
||||||
} else if (!isNew) {
|
} else if (!isNew) {
|
||||||
eventHub.dispatch(StatusChangedEvent(sentStatus))
|
eventHub.dispatch(StatusChangedEvent(sentStatus as Status))
|
||||||
} else {
|
} else {
|
||||||
eventHub.dispatch(StatusComposedEvent(sentStatus))
|
eventHub.dispatch(StatusComposedEvent(sentStatus as Status))
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationManager.cancel(statusId)
|
notificationManager.cancel(statusId)
|
||||||
|
|
Loading…
Reference in New Issue