made buffer working

This commit is contained in:
Mariotaku Lee 2017-03-25 23:53:49 +08:00
parent 57ec043a8a
commit 355ee72a0f
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
6 changed files with 88 additions and 52 deletions

View File

@ -65,7 +65,6 @@ public interface IntentConstants {
String INTENT_ACTION_EXTENSION_SETTINGS = INTENT_PACKAGE_PREFIX + "EXTENSION_SETTINGS"; String INTENT_ACTION_EXTENSION_SETTINGS = INTENT_PACKAGE_PREFIX + "EXTENSION_SETTINGS";
String INTENT_ACTION_UPDATE_STATUS = INTENT_PACKAGE_PREFIX + "UPDATE_STATUS"; String INTENT_ACTION_UPDATE_STATUS = INTENT_PACKAGE_PREFIX + "UPDATE_STATUS";
String INTENT_ACTION_SCHEDULE_STATUS = INTENT_PACKAGE_PREFIX + "SCHEDULE_STATUS";
String INTENT_ACTION_SEND_DIRECT_MESSAGE = INTENT_PACKAGE_PREFIX + "SEND_DIRECT_MESSAGE"; String INTENT_ACTION_SEND_DIRECT_MESSAGE = INTENT_PACKAGE_PREFIX + "SEND_DIRECT_MESSAGE";
String INTENT_ACTION_DISCARD_DRAFT = INTENT_PACKAGE_PREFIX + "DISCARD_DRAFT"; String INTENT_ACTION_DISCARD_DRAFT = INTENT_PACKAGE_PREFIX + "DISCARD_DRAFT";
String INTENT_ACTION_SEND_DRAFT = INTENT_PACKAGE_PREFIX + "SEND_DRAFT"; String INTENT_ACTION_SEND_DRAFT = INTENT_PACKAGE_PREFIX + "SEND_DRAFT";

View File

@ -1383,12 +1383,8 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
update.in_reply_to_status = inReplyToStatus update.in_reply_to_status = inReplyToStatus
update.is_possibly_sensitive = isPossiblySensitive update.is_possibly_sensitive = isPossiblySensitive
update.attachment_url = (draft?.action_extras as? UpdateStatusActionExtras)?.attachmentUrl update.attachment_url = (draft?.action_extras as? UpdateStatusActionExtras)?.attachmentUrl
val scheduleInfo = this.scheduleInfo LengthyOperationsService.updateStatusesAsync(this, action, statuses = update,
if (scheduleInfo != null) { scheduleInfo = scheduleInfo)
LengthyOperationsService.scheduleStatus(this, action, update, scheduleInfo)
} else {
LengthyOperationsService.updateStatusesAsync(this, action, update)
}
if (preferences[noCloseAfterTweetSentKey] && inReplyToStatus == null) { if (preferences[noCloseAfterTweetSentKey] && inReplyToStatus == null) {
possiblySensitive = false possiblySensitive = false
shouldSaveAccounts = true shouldSaveAccounts = true

View File

@ -95,9 +95,6 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
INTENT_ACTION_UPDATE_STATUS -> { INTENT_ACTION_UPDATE_STATUS -> {
handleUpdateStatusIntent(intent) handleUpdateStatusIntent(intent)
} }
INTENT_ACTION_SCHEDULE_STATUS -> {
handleScheduleStatusIntent(intent)
}
INTENT_ACTION_SEND_DIRECT_MESSAGE -> { INTENT_ACTION_SEND_DIRECT_MESSAGE -> {
handleSendDirectMessageIntent(intent) handleSendDirectMessageIntent(intent)
} }
@ -138,7 +135,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
when (draft.action_type) { when (draft.action_type) {
Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2,
Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> { Draft.Action.UPDATE_STATUS, Draft.Action.REPLY, Draft.Action.QUOTE -> {
updateStatuses(ParcelableStatusUpdateUtils.fromDraftItem(this, draft)) updateStatuses(arrayOf(ParcelableStatusUpdateUtils.fromDraftItem(this, draft)))
} }
Draft.Action.SEND_DIRECT_MESSAGE_COMPAT, Draft.Action.SEND_DIRECT_MESSAGE -> { Draft.Action.SEND_DIRECT_MESSAGE_COMPAT, Draft.Action.SEND_DIRECT_MESSAGE -> {
val extras = draft.action_extras as? SendDirectMessageActionExtras ?: return val extras = draft.action_extras as? SendDirectMessageActionExtras ?: return
@ -224,6 +221,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
private fun handleUpdateStatusIntent(intent: Intent) { private fun handleUpdateStatusIntent(intent: Intent) {
val status = intent.getParcelableExtra<ParcelableStatusUpdate>(EXTRA_STATUS) val status = intent.getParcelableExtra<ParcelableStatusUpdate>(EXTRA_STATUS)
val statusParcelables = intent.getParcelableArrayExtra(EXTRA_STATUSES) val statusParcelables = intent.getParcelableArrayExtra(EXTRA_STATUSES)
val scheduleInfo = intent.getParcelableExtra<ScheduleInfo>(EXTRA_SCHEDULE_INFO)
val statuses: Array<ParcelableStatusUpdate> val statuses: Array<ParcelableStatusUpdate>
if (statusParcelables != null) { if (statusParcelables != null) {
statuses = statusParcelables.toTypedArray(ParcelableStatusUpdate.CREATOR) statuses = statusParcelables.toTypedArray(ParcelableStatusUpdate.CREATOR)
@ -234,19 +232,10 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
@Draft.Action @Draft.Action
val actionType = intent.getStringExtra(EXTRA_ACTION) val actionType = intent.getStringExtra(EXTRA_ACTION)
statuses.forEach { it.draft_action = actionType } statuses.forEach { it.draft_action = actionType }
updateStatuses(*statuses) updateStatuses(statuses, scheduleInfo)
} }
private fun handleScheduleStatusIntent(intent: Intent) { private fun updateStatuses(statuses: Array<ParcelableStatusUpdate>, scheduleInfo: ScheduleInfo? = null) {
val status = intent.getParcelableExtra<ParcelableStatusUpdate>(EXTRA_STATUS)
val scheduleInfo = intent.getParcelableExtra<ScheduleInfo>(EXTRA_SCHEDULE_INFO)
@Draft.Action
val actionType = intent.getStringExtra(EXTRA_ACTION)
status.draft_action = actionType
}
private fun updateStatuses(vararg statuses: ParcelableStatusUpdate) {
val context = this val context = this
val builder = Builder(context) val builder = Builder(context)
startForeground(NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(context, startForeground(NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(context,
@ -316,7 +305,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
} }
}) })
task.callback = this task.callback = this
task.params = item task.params = Pair(item, scheduleInfo)
invokeBeforeExecute(task) invokeBeforeExecute(task)
val result = ManualTaskStarter.invokeExecute(task) val result = ManualTaskStarter.invokeExecute(task)
@ -465,19 +454,10 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
} }
fun updateStatusesAsync(context: Context, @Draft.Action action: String, fun updateStatusesAsync(context: Context, @Draft.Action action: String,
vararg statuses: ParcelableStatusUpdate) { vararg statuses: ParcelableStatusUpdate, scheduleInfo: ScheduleInfo? = null) {
val intent = Intent(context, LengthyOperationsService::class.java) val intent = Intent(context, LengthyOperationsService::class.java)
intent.action = INTENT_ACTION_UPDATE_STATUS intent.action = INTENT_ACTION_UPDATE_STATUS
intent.putExtra(EXTRA_STATUSES, statuses) intent.putExtra(EXTRA_STATUSES, statuses)
intent.putExtra(EXTRA_ACTION, action)
context.startService(intent)
}
fun scheduleStatus(context: Context, @Draft.Action action: String,
status: ParcelableStatusUpdate, scheduleInfo: ScheduleInfo) {
val intent = Intent(context, LengthyOperationsService::class.java)
intent.action = INTENT_ACTION_SCHEDULE_STATUS
intent.putExtra(EXTRA_STATUS, status)
intent.putExtra(EXTRA_SCHEDULE_INFO, scheduleInfo) intent.putExtra(EXTRA_SCHEDULE_INFO, scheduleInfo)
intent.putExtra(EXTRA_ACTION, action) intent.putExtra(EXTRA_ACTION, action)
context.startService(intent) context.startService(intent)

View File

@ -7,6 +7,7 @@ import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.media.MediaPreloader import org.mariotaku.twidere.util.media.MediaPreloader
import org.mariotaku.twidere.util.schedule.StatusScheduleController
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -33,6 +34,11 @@ abstract class BaseAbstractTask<Params, Result, Callback>(val context: Context)
lateinit var readStateManager: ReadStateManager lateinit var readStateManager: ReadStateManager
@Inject @Inject
lateinit var userColorNameManager: UserColorNameManager lateinit var userColorNameManager: UserColorNameManager
@Inject
lateinit var scheduleControllerFactory: StatusScheduleController.Factory
val scheduleController: StatusScheduleController?
get() = scheduleControllerFactory.newInstance(context)
init { init {
injectMembers() injectMembers()

View File

@ -43,6 +43,7 @@ import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.account.AccountExtras import org.mariotaku.twidere.model.account.AccountExtras
import org.mariotaku.twidere.model.analyzer.UpdateStatus import org.mariotaku.twidere.model.analyzer.UpdateStatus
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras import org.mariotaku.twidere.model.draft.UpdateStatusActionExtras
import org.mariotaku.twidere.model.schedule.ScheduleInfo
import org.mariotaku.twidere.model.util.ParcelableLocationUtils import org.mariotaku.twidere.model.util.ParcelableLocationUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.preference.ServicePickerPreference import org.mariotaku.twidere.preference.ServicePickerPreference
@ -63,14 +64,15 @@ import java.util.concurrent.TimeUnit
class UpdateStatusTask( class UpdateStatusTask(
context: Context, context: Context,
internal val stateCallback: UpdateStatusTask.StateCallback internal val stateCallback: UpdateStatusTask.StateCallback
) : BaseAbstractTask<ParcelableStatusUpdate, UpdateStatusTask.UpdateStatusResult, Any?>(context) { ) : BaseAbstractTask<Pair<ParcelableStatusUpdate, ScheduleInfo?>, UpdateStatusTask.UpdateStatusResult, Any?>(context) {
override fun doLongOperation(params: ParcelableStatusUpdate): UpdateStatusResult { override fun doLongOperation(params: Pair<ParcelableStatusUpdate, ScheduleInfo?>): UpdateStatusResult {
val draftId = saveDraft(params) val (update, info) = params
val draftId = saveDraft(update)
microBlogWrapper.addSendingDraftId(draftId) microBlogWrapper.addSendingDraftId(draftId)
try { try {
val result = doUpdateStatus(params, draftId) val result = doUpdateStatus(update, info, draftId)
deleteOrUpdateDraft(params, result, draftId) deleteOrUpdateDraft(update, result, draftId)
return result return result
} catch (e: UpdateStatusException) { } catch (e: UpdateStatusException) {
return UpdateStatusResult(e, draftId) return UpdateStatusResult(e, draftId)
@ -85,9 +87,7 @@ class UpdateStatusTask(
override fun afterExecute(handler: Any?, result: UpdateStatusResult) { override fun afterExecute(handler: Any?, result: UpdateStatusResult) {
stateCallback.afterExecute(result) stateCallback.afterExecute(result)
if (params != null) { logUpdateStatus(params.first, result)
logUpdateStatus(params, result)
}
} }
private fun logUpdateStatus(statusUpdate: ParcelableStatusUpdate, result: UpdateStatusResult) { private fun logUpdateStatus(statusUpdate: ParcelableStatusUpdate, result: UpdateStatusResult) {
@ -100,7 +100,8 @@ class UpdateStatusTask(
} }
@Throws(UpdateStatusException::class) @Throws(UpdateStatusException::class)
private fun doUpdateStatus(update: ParcelableStatusUpdate, draftId: Long): UpdateStatusResult { private fun doUpdateStatus(update: ParcelableStatusUpdate, info: ScheduleInfo?, draftId: Long):
UpdateStatusResult {
val app = TwidereApplication.getInstance(context) val app = TwidereApplication.getInstance(context)
val uploader = getMediaUploader(app) val uploader = getMediaUploader(app)
val shortener = getStatusShortener(app) val shortener = getStatusShortener(app)
@ -109,10 +110,14 @@ class UpdateStatusTask(
val result: UpdateStatusResult val result: UpdateStatusResult
try { try {
uploadMedia(uploader, update, pendingUpdate) uploadMedia(uploader, update, info, pendingUpdate)
shortenStatus(shortener, update, pendingUpdate) shortenStatus(shortener, update, pendingUpdate)
if (info != null) {
result = requestScheduleStatus(update, pendingUpdate, info, draftId)
} else {
result = requestUpdateStatus(update, pendingUpdate, draftId) result = requestUpdateStatus(update, pendingUpdate, draftId)
}
mediaUploadCallback(uploader, pendingUpdate, result) mediaUploadCallback(uploader, pendingUpdate, result)
statusShortenCallback(shortener, pendingUpdate, result) statusShortenCallback(shortener, pendingUpdate, result)
@ -131,7 +136,8 @@ class UpdateStatusTask(
return result return result
} }
private fun deleteOrUpdateDraft(update: ParcelableStatusUpdate, result: UpdateStatusResult, draftId: Long) { private fun deleteOrUpdateDraft(update: ParcelableStatusUpdate, result: UpdateStatusResult,
draftId: Long) {
val where = Expression.equalsArgs(Drafts._ID).sql val where = Expression.equalsArgs(Drafts._ID).sql
val whereArgs = arrayOf(draftId.toString()) val whereArgs = arrayOf(draftId.toString())
var hasError = false var hasError = false
@ -157,12 +163,13 @@ class UpdateStatusTask(
@Throws(UploadException::class) @Throws(UploadException::class)
private fun uploadMedia(uploader: MediaUploaderInterface?, private fun uploadMedia(uploader: MediaUploaderInterface?,
update: ParcelableStatusUpdate, update: ParcelableStatusUpdate,
info: ScheduleInfo?,
pendingUpdate: PendingStatusUpdate) { pendingUpdate: PendingStatusUpdate) {
stateCallback.onStartUploadingMedia() stateCallback.onStartUploadingMedia()
if (uploader == null) { if (uploader != null) {
uploadMediaWithDefaultProvider(update, pendingUpdate)
} else {
uploadMediaWithExtension(uploader, update, pendingUpdate) uploadMediaWithExtension(uploader, update, pendingUpdate)
} else if (info == null) {
uploadMediaWithDefaultProvider(update, pendingUpdate)
} }
} }
@ -241,6 +248,29 @@ class UpdateStatusTask(
} }
} }
@Throws(UpdateStatusException::class)
private fun requestScheduleStatus(
statusUpdate: ParcelableStatusUpdate,
pendingUpdate: PendingStatusUpdate,
scheduleInfo: ScheduleInfo,
draftId: Long
): UpdateStatusResult {
stateCallback.onUpdatingStatus()
val controller = scheduleController ?: run {
throw SchedulerNotFoundException("No scheduler found")
}
try {
controller.scheduleStatus(statusUpdate, pendingUpdate.overrideTexts, scheduleInfo)
} catch (e: ScheduleException) {
return UpdateStatusResult(e, draftId)
}
return UpdateStatusResult(pendingUpdate.length, draftId)
}
@Throws(UpdateStatusException::class) @Throws(UpdateStatusException::class)
private fun requestUpdateStatus( private fun requestUpdateStatus(
statusUpdate: ParcelableStatusUpdate, statusUpdate: ParcelableStatusUpdate,
@ -383,7 +413,8 @@ class UpdateStatusTask(
return microBlog.updateStatus(status) return microBlog.updateStatus(status)
} }
private fun statusShortenCallback(shortener: StatusShortenerInterface?, pendingUpdate: PendingStatusUpdate, updateResult: UpdateStatusResult) { private fun statusShortenCallback(shortener: StatusShortenerInterface?,
pendingUpdate: PendingStatusUpdate, updateResult: UpdateStatusResult) {
if (shortener == null || !shortener.waitForService()) return if (shortener == null || !shortener.waitForService()) return
for (i in 0..pendingUpdate.length - 1) { for (i in 0..pendingUpdate.length - 1) {
val shortenResult = pendingUpdate.statusShortenResults[i] val shortenResult = pendingUpdate.statusShortenResults[i]
@ -393,7 +424,8 @@ class UpdateStatusTask(
} }
} }
private fun mediaUploadCallback(uploader: MediaUploaderInterface?, pendingUpdate: PendingStatusUpdate, updateResult: UpdateStatusResult) { private fun mediaUploadCallback(uploader: MediaUploaderInterface?,
pendingUpdate: PendingStatusUpdate, updateResult: UpdateStatusResult) {
if (uploader == null || !uploader.waitForService()) return if (uploader == null || !uploader.waitForService()) return
for (i in 0..pendingUpdate.length - 1) { for (i in 0..pendingUpdate.length - 1) {
val uploadResult = pendingUpdate.mediaUploadResults[i] val uploadResult = pendingUpdate.mediaUploadResults[i]
@ -498,7 +530,7 @@ class UpdateStatusTask(
val exception: UpdateStatusException? val exception: UpdateStatusException?
val draftId: Long val draftId: Long
val succeed: Boolean get() = exception == null && statuses.isNotEmpty() && statuses.none { it == null } val succeed: Boolean get() = exception == null && exceptions.none { it != null }
constructor(count: Int, draftId: Long) { constructor(count: Int, draftId: Long) {
this.statuses = arrayOfNulls(count) this.statuses = arrayOfNulls(count)
@ -529,6 +561,7 @@ class UpdateStatusTask(
} }
class UploaderNotFoundException(message: String) : UpdateStatusException(message) class UploaderNotFoundException(message: String) : UpdateStatusException(message)
class SchedulerNotFoundException(message: String) : UpdateStatusException(message)
class UploadException : UpdateStatusException { class UploadException : UpdateStatusException {
@ -543,6 +576,17 @@ class UpdateStatusTask(
constructor(message: String) : super(message) constructor(message: String) : super(message)
} }
class ScheduleException : UpdateStatusException {
constructor() : super()
constructor(detailMessage: String, throwable: Throwable) : super(detailMessage, throwable)
constructor(throwable: Throwable) : super(throwable)
constructor(message: String) : super(message)
}
class ExtensionVersionMismatchException : AbsServiceInterface.CheckServiceException() class ExtensionVersionMismatchException : AbsServiceInterface.CheckServiceException()
class ShortenerNotFoundException : UpdateStatusException() class ShortenerNotFoundException : UpdateStatusException()

View File

@ -21,8 +21,10 @@ package org.mariotaku.twidere.util.schedule
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.support.annotation.WorkerThread
import org.mariotaku.twidere.model.ParcelableStatusUpdate import org.mariotaku.twidere.model.ParcelableStatusUpdate
import org.mariotaku.twidere.model.schedule.ScheduleInfo import org.mariotaku.twidere.model.schedule.ScheduleInfo
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
import java.util.* import java.util.*
/** /**
@ -30,18 +32,27 @@ import java.util.*
*/ */
interface StatusScheduleController { interface StatusScheduleController {
fun scheduleStatus(statusUpdate: ParcelableStatusUpdate, scheduleInfo: ScheduleInfo)
@WorkerThread
@Throws(UpdateStatusTask.ScheduleException::class)
fun scheduleStatus(statusUpdate: ParcelableStatusUpdate, overrideTexts: Array<String>,
scheduleInfo: ScheduleInfo)
fun createSetScheduleIntent(): Intent fun createSetScheduleIntent(): Intent
interface Factory { interface Factory {
fun newInstance(context: Context): StatusScheduleController? fun newInstance(context: Context): StatusScheduleController?
fun parseInfo(json: String): ScheduleInfo?
companion object { companion object {
val instance: Factory get() = ServiceLoader.load(Factory::class.java)?.firstOrNull() ?: NullFactory val instance: Factory get() = ServiceLoader.load(Factory::class.java)?.firstOrNull() ?: NullFactory
private object NullFactory : Factory { private object NullFactory : Factory {
override fun newInstance(context: Context) = null override fun newInstance(context: Context) = null
override fun parseInfo(json: String): ScheduleInfo? = null
} }
} }
} }