diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt index 34c85813b..8f1d0701f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ComposeAutoCompleteAdapter.kt @@ -61,7 +61,7 @@ class ComposeAutoCompleteAdapter(context: Context) : SimpleCursorAdapter(context private var mExtraIdIdx: Int = 0 private var mValueIdx: Int = 0 var accountKey: UserKey? = null - private var mToken: Char = ' ' + private var token: Char = ' ' init { GeneralComponentHelper.build(context).inject(this) @@ -118,14 +118,14 @@ class ComposeAutoCompleteAdapter(context: Context) : SimpleCursorAdapter(context return cursor.getString(mValueIdx) } - override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? { - if (TextUtils.isEmpty(constraint)) return null + override fun runQueryOnBackgroundThread(constraint: CharSequence?): Cursor? { + if (constraint == null || constraint.isEmpty()) return null val token = constraint[0] - if (getNormalizedSymbol(token) == getNormalizedSymbol(mToken)) { + if (getNormalizedSymbol(token) == getNormalizedSymbol(this.token)) { val filter = filterQueryProvider if (filter != null) return filter.runQuery(constraint) } - mToken = token + this.token = token val builder = Suggestions.AutoComplete.CONTENT_URI.buildUpon() builder.appendQueryParameter(QUERY_PARAM_QUERY, constraint.subSequence(1, constraint.length).toString()) when (getNormalizedSymbol(token)) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt index 62b3db9b0..ecbdc825f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt @@ -114,22 +114,25 @@ class UpdateStatusTask( val pendingUpdate = PendingStatusUpdate(update) - uploadMedia(uploader, update, pendingUpdate) - shortenStatus(shortener, update, pendingUpdate) - val result: UpdateStatusResult try { - result = requestUpdateStatus(update, pendingUpdate, draftId) - } catch (e: IOException) { - return UpdateStatusResult(UpdateStatusException(e), draftId) - } + uploadMedia(uploader, update, pendingUpdate) + shortenStatus(shortener, update, pendingUpdate) - mediaUploadCallback(uploader, pendingUpdate, result) - statusShortenCallback(shortener, pendingUpdate, result) + try { + result = requestUpdateStatus(update, pendingUpdate, draftId) + } catch (e: IOException) { + return UpdateStatusResult(UpdateStatusException(e), draftId) + } - // Cleanup - pendingUpdate.deleteOnSuccess.forEach { delete -> - delete.delete(context) + mediaUploadCallback(uploader, pendingUpdate, result) + statusShortenCallback(shortener, pendingUpdate, result) + + // Cleanup + pendingUpdate.deleteOnSuccess.forEach { item -> item.delete(context) } + } finally { + // Cleanup + pendingUpdate.deleteAlways.forEach { item -> item.delete(context) } } return result } @@ -329,9 +332,10 @@ class UpdateStatusTask( if (pendingUpdate.sharedMediaIds != null) { mediaIds = pendingUpdate.sharedMediaIds } else { - val (ids, deleteOnSuccess) = uploadAllMediaShared(upload, update, ownerIds, true) + val (ids, deleteOnSuccess, deleteAlways) = uploadAllMediaShared(upload, update, ownerIds, true) mediaIds = ids - deleteOnSuccess?.addAllTo(pendingUpdate.deleteOnSuccess) + deleteOnSuccess.addAllTo(pendingUpdate.deleteOnSuccess) + deleteAlways.addAllTo(pendingUpdate.deleteAlways) pendingUpdate.sharedMediaIds = mediaIds } } @@ -342,9 +346,10 @@ class UpdateStatusTask( AccountType.STATUSNET -> { // TODO use their native API val upload = account.newMicroBlogInstance(context, cls = TwitterUpload::class.java) - val (ids, deleteOnSuccess) = uploadAllMediaShared(upload, update, ownerIds, false) + val (ids, deleteOnSuccess, deleteAlways) = uploadAllMediaShared(upload, update, ownerIds, false) mediaIds = ids - deleteOnSuccess?.addAllTo(pendingUpdate.deleteOnSuccess) + deleteOnSuccess.addAllTo(pendingUpdate.deleteOnSuccess) + deleteAlways.addAllTo(pendingUpdate.deleteAlways) } else -> { mediaIds = null @@ -454,8 +459,9 @@ class UpdateStatusTask( update: ParcelableStatusUpdate, ownerIds: Array, chucked: Boolean - ): Pair, List?> { + ): SharedMediaUploadResult { val deleteOnSuccess = ArrayList() + val deleteAlways = ArrayList() val mediaIds = update.media.mapIndexed { index, media -> val resp: MediaUploadResponse //noinspection TryWithIdenticalCatches @@ -486,6 +492,7 @@ class UpdateStatusTask( Utils.closeSilently(body) } body?.deleteOnSuccess?.addAllTo(deleteOnSuccess) + body?.deleteAlways?.addAllTo(deleteAlways) if (media.alt_text?.isNotEmpty() ?: false) { try { upload.createMetadata(NewMediaMetadata(resp.id, media.alt_text)) @@ -495,7 +502,7 @@ class UpdateStatusTask( } return@mapIndexed resp.id } - return Pair(mediaIds.toTypedArray(), deleteOnSuccess) + return SharedMediaUploadResult(mediaIds.toTypedArray(), deleteOnSuccess, deleteAlways) } @@ -590,6 +597,7 @@ class UpdateStatusTask( val statusShortenResults: Array = arrayOfNulls(length) val deleteOnSuccess: ArrayList = arrayListOf() + val deleteAlways: ArrayList = arrayListOf() } @@ -704,7 +712,8 @@ class UpdateStatusTask( data class MediaStreamBody( val body: Body, val geometry: Point?, - val deleteOnSuccess: List? + val deleteOnSuccess: List?, + val deleteAlways: List? ) : Closeable { override fun close() { body.close() @@ -717,7 +726,12 @@ class UpdateStatusTask( data class UriMediaDeletionItem(val uri: Uri) : MediaDeletionItem { override fun delete(context: Context): Boolean { - return PNCUtils.deleteMedia(context, uri) + try { + return PNCUtils.deleteMedia(context, uri) + } catch (e: SecurityException) { + // Ignore + return false + } } } @@ -728,6 +742,12 @@ class UpdateStatusTask( } + internal data class SharedMediaUploadResult( + val ids: Array, + val deleteOnSuccess: List, + val deleteAlways: List + ) + companion object { private val BULK_SIZE = 256 * 1024// 128 Kib @@ -772,9 +792,11 @@ class UpdateStatusTask( cis.setReadListener(readListener) val mimeType = data?.type ?: mediaType ?: "application/octet-stream" val body = FileBody(cis, "attachment", cis.length(), ContentType.parse(mimeType)) - val deletionList: MutableList = mutableListOf(UriMediaDeletionItem(mediaUri)) - data?.deleteOnSuccess?.addAllTo(deletionList) - return MediaStreamBody(body, data?.geometry, deletionList) + val deleteOnSuccess: MutableList = mutableListOf(UriMediaDeletionItem(mediaUri)) + val deleteAlways: MutableList = mutableListOf() + data?.deleteOnSuccess?.addAllTo(deleteOnSuccess) + data?.deleteAlways?.addAllTo(deleteAlways) + return MediaStreamBody(body, data?.geometry, deleteOnSuccess, deleteAlways) } @@ -820,7 +842,7 @@ class UpdateStatusTask( } } return MediaStreamData(ContentLengthInputStream(tempFile), mediaType, size, - listOf(FileMediaDeletionItem(tempFile))) + null, listOf(FileMediaDeletionItem(tempFile))) } } return null @@ -862,14 +884,15 @@ class UpdateStatusTask( return null } return MediaStreamData(ContentLengthInputStream(tempFile.inputStream(), - tempFile.length()), defaultType, null, listOf(FileMediaDeletionItem(tempFile))) + tempFile.length()), defaultType, null, null, listOf(FileMediaDeletionItem(tempFile))) } internal class MediaStreamData( val stream: ContentLengthInputStream?, val type: String?, val geometry: Point?, - val deleteOnSuccess: List? + val deleteOnSuccess: List?, + val deleteAlways: List? )