From 67c086b545ab5e0444724f8e598058cee059b245 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Sun, 12 Nov 2017 10:51:33 +0800 Subject: [PATCH] removed some AbsTask implementations --- .../MessageConversationInfoFragment.kt | 12 +- .../twidere/promise/ConversationPromises.kt | 47 +++++++ .../twidere/promise/MessagePromises.kt | 49 ++++++- .../twidere/receiver/NotificationReceiver.kt | 6 +- .../twitter/message/AddParticipantsTask.kt | 97 ------------- .../message/BatchMarkMessageReadTask.kt | 89 ------------ .../twitter/message/MarkMessageReadTask.kt | 133 ------------------ 7 files changed, 95 insertions(+), 338 deletions(-) delete mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/AddParticipantsTask.kt delete mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/BatchMarkMessageReadTask.kt delete mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt index 6e553fb82..d4c00d5cf 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt @@ -52,7 +52,6 @@ import nl.komponents.kovenant.task import nl.komponents.kovenant.then import nl.komponents.kovenant.ui.alwaysUi import nl.komponents.kovenant.ui.successUi -import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.chameleon.Chameleon import org.mariotaku.chameleon.ChameleonUtils import org.mariotaku.kpreferences.get @@ -93,7 +92,6 @@ import org.mariotaku.twidere.promise.ConversationPromises import org.mariotaku.twidere.promise.MessagePromises import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.task.status.UpdateStatusTask -import org.mariotaku.twidere.task.twitter.message.AddParticipantsTask import org.mariotaku.twidere.util.IntentUtils import org.mariotaku.twidere.view.holder.SimpleUserViewHolder import java.lang.ref.WeakReference @@ -318,15 +316,13 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment, private fun performAddParticipant(user: ParcelableUser) { ProgressDialogFragment.show(childFragmentManager, "add_participant_progress") - val weakThis = WeakReference(this) - val task = AddParticipantsTask(context, accountKey, conversationId, listOf(user)) - task.callback = callback@ { succeed -> - val f = weakThis.get() ?: return@callback - f.dismissDialogThen("add_participant_progress") { + val weakThis by weak(this) + ConversationPromises.getInstance(context).addParticipants(accountKey, + conversationId, listOf(user)).alwaysUi { + weakThis?.dismissDialogThen("add_participant_progress") { loaderManager.restartLoader(0, null, this) } } - TaskStarter.execute(task) } private fun performSetNotificationDisabled(disabled: Boolean) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/ConversationPromises.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/ConversationPromises.kt index d6097e47d..e1b90fe3a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/ConversationPromises.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/ConversationPromises.kt @@ -24,13 +24,20 @@ import android.app.Application import android.content.Context import nl.komponents.kovenant.Promise import nl.komponents.kovenant.task +import org.mariotaku.ktextension.mapToArray import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.twidere.R import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.exception.AccountNotFoundException +import org.mariotaku.twidere.extension.getDetailsOrThrow +import org.mariotaku.twidere.extension.model.addParticipants import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.notificationDisabled import org.mariotaku.twidere.model.AccountDetails +import org.mariotaku.twidere.model.ParcelableMessageConversation +import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.task.twitter.message.GetMessagesTask @@ -39,6 +46,8 @@ import org.mariotaku.twidere.util.SingletonHolder class ConversationPromises private constructor(private val application: Application) { + private val profileImageSize: String = application.getString(R.string.profile_image_size) + fun setNotificationDisabled(accountKey: UserKey, conversationId: String, notificationDisabled: Boolean): Promise = task { val account = AccountUtils.getAccountDetails(AccountManager.get(application), @@ -48,6 +57,44 @@ class ConversationPromises private constructor(private val application: Applicat return@task true } + fun addParticipants(accountKey: UserKey, conversationId: String, + participants: Collection): Promise = task { + val account = AccountManager.get(application).getDetailsOrThrow(accountKey, true) + val conversation = DataStoreUtils.findMessageConversation(application, accountKey, conversationId) + if (conversation != null && conversation.is_temp) { + val addData = GetMessagesTask.DatabaseUpdateData(listOf(conversation), emptyList()) + conversation.addParticipants(participants) + GetMessagesTask.storeMessages(application, addData, account, showNotification = false) + return@task true + } + + val addData = requestAddParticipants(account, conversationId, conversation, participants) + GetMessagesTask.storeMessages(application, addData, account, showNotification = false) + return@task true + } + + private fun requestAddParticipants(account: AccountDetails, conversationId: String, + conversation: ParcelableMessageConversation?, participants: Collection): + GetMessagesTask.DatabaseUpdateData { + when (account.type) { + AccountType.TWITTER -> { + if (account.isOfficial(application)) { + val microBlog = account.newMicroBlogInstance(application, cls = MicroBlog::class.java) + val ids = participants.mapToArray { it.key.id } + val response = microBlog.addParticipants(conversationId, ids) + if (conversation != null) { + conversation.addParticipants(participants) + return GetMessagesTask.DatabaseUpdateData(listOf(conversation), emptyList()) + } + return GetMessagesTask.createDatabaseUpdateData(application, account, response, + profileImageSize) + } + } + + } + throw MicroBlogException("Adding participants is not supported") + } + private fun requestSetNotificationDisabled(account: AccountDetails, conversationId: String, notificationDisabled: Boolean): GetMessagesTask.DatabaseUpdateData { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt index 583a02ce8..5bf4167e5 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt @@ -28,10 +28,14 @@ import com.squareup.otto.Bus import nl.komponents.kovenant.Promise import nl.komponents.kovenant.task import nl.komponents.kovenant.ui.successUi +import org.mariotaku.ktextension.forEachRow +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.OrderBy +import org.mariotaku.sqliteqb.library.Table import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.extension.getDetailsOrThrow import org.mariotaku.twidere.extension.model.isOfficial @@ -47,11 +51,9 @@ import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras import org.mariotaku.twidere.provider.TwidereDataStore.Messages import org.mariotaku.twidere.task.twitter.message.SendMessageTask -import org.mariotaku.twidere.util.DataStoreUtils -import org.mariotaku.twidere.util.SingletonHolder +import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.dagger.GeneralComponent -import org.mariotaku.twidere.util.updateItems import javax.inject.Inject class MessagePromises private constructor(private val application: Application) { @@ -130,7 +132,7 @@ class MessagePromises private constructor(private val application: Application) val microBlog = account.newMicroBlogInstance(application, cls = MicroBlog::class.java) val conversation = DataStoreUtils.findMessageConversation(application, accountKey, conversationId) val lastReadEvent = conversation?.let { - return@let performMarkRead(microBlog, account, conversation) + return@let performMarkRead(account, conversation) } ?: return@task false updateLocalLastRead(application.contentResolver, accountKey, conversationId, lastReadEvent) return@task true @@ -138,6 +140,39 @@ class MessagePromises private constructor(private val application: Application) bus.post(UnreadCountUpdatedEvent(-1)) } + + fun batchMarkRead(accountKey: UserKey, markTimestampBefore: Long): Promise = task { + val cr = application.contentResolver + val projection = (Messages.Conversations.COLUMNS + Messages.Conversations.UNREAD_COUNT).map { + TwidereQueryBuilder.mapConversationsProjection(it) + }.toTypedArray() + + val unreadWhere = Expression.greaterThan(Columns.Column(Table(Messages.Conversations.TABLE_NAME), + Messages.Conversations.LAST_READ_TIMESTAMP), markTimestampBefore) + val unreadHaving = Expression.greaterThan(Messages.Conversations.UNREAD_COUNT, 0) + + val cRef = cr.getUnreadMessagesEntriesCursorReference(projection, arrayOf(accountKey), + unreadWhere, null, unreadHaving, null) ?: return@task false + val account = AccountManager.get(application).getDetailsOrThrow(accountKey, true) + cRef.use { (cur) -> + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) + cur.forEachRow { c, _ -> + val conversation = indices.newObject(c) + try { + val lastReadEvent = performMarkRead(account, conversation) ?: return@forEachRow false + updateLocalLastRead(cr, account.key, conversation.id, + lastReadEvent) + return@forEachRow true + } catch (e: MicroBlogException) { + return@forEachRow false + } + } + } + return@task true + }.successUi { + bus.post(UnreadCountUpdatedEvent(-1)) + } + private fun clearMessagesSync(account: AccountDetails, conversationId: String): Boolean { val messagesWhere = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY), Expression.equalsArgs(Messages.CONVERSATION_ID)).sql @@ -206,11 +241,11 @@ class MessagePromises private constructor(private val application: Application) } @Throws(MicroBlogException::class) - internal fun performMarkRead(microBlog: MicroBlog, account: AccountDetails, - conversation: ParcelableMessageConversation): Pair? { + private fun performMarkRead(account: AccountDetails, conversation: ParcelableMessageConversation): Pair? { val cr = application.contentResolver when (account.type) { AccountType.TWITTER -> { + val microBlog = account.newMicroBlogInstance(application, cls = MicroBlog::class.java) if (account.isOfficial(application)) { val event = (conversation.conversation_extras as? TwitterOfficialConversationExtras)?.maxReadEvent ?: run { val message = cr.findRecentMessage(account.key, conversation.id) ?: return null @@ -230,7 +265,7 @@ class MessagePromises private constructor(private val application: Application) return Pair(message.id, message.timestamp) } - internal fun updateLocalLastRead(cr: ContentResolver, accountKey: UserKey, + private fun updateLocalLastRead(cr: ContentResolver, accountKey: UserKey, conversationId: String, lastRead: Pair) { val values = ContentValues() values.put(Messages.Conversations.LAST_READ_ID, lastRead.first) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/receiver/NotificationReceiver.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/receiver/NotificationReceiver.kt index 7548d8b3a..3761362c5 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/receiver/NotificationReceiver.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/receiver/NotificationReceiver.kt @@ -22,7 +22,6 @@ package org.mariotaku.twidere.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.kpreferences.set import org.mariotaku.ktextension.toLongOr import org.mariotaku.twidere.TwidereConstants.* @@ -31,7 +30,7 @@ import org.mariotaku.twidere.annotation.ReadPositionTag import org.mariotaku.twidere.constant.IntentConstants.BROADCAST_NOTIFICATION_DELETED import org.mariotaku.twidere.constant.promotionsEnabledKey import org.mariotaku.twidere.model.UserKey -import org.mariotaku.twidere.task.twitter.message.BatchMarkMessageReadTask +import org.mariotaku.twidere.promise.MessagePromises import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.dagger.DependencyHolder @@ -77,9 +76,8 @@ class NotificationReceiver : BroadcastReceiver() { NotificationType.DIRECT_MESSAGES -> { if (accountKey == null) return val appContext = context.applicationContext - val task = BatchMarkMessageReadTask(appContext, accountKey, + MessagePromises.getInstance(appContext).batchMarkRead(accountKey, paramReadPosition.toLongOr(-1L)) - TaskStarter.execute(task) } } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/AddParticipantsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/AddParticipantsTask.kt deleted file mode 100644 index 23358f86a..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/AddParticipantsTask.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2017 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.task.twitter.message - -import android.accounts.AccountManager -import android.content.Context -import org.mariotaku.ktextension.mapToArray -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.twidere.R -import org.mariotaku.twidere.annotation.AccountType -import org.mariotaku.twidere.extension.getDetailsOrThrow -import org.mariotaku.twidere.extension.model.addParticipants -import org.mariotaku.twidere.extension.model.isOfficial -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableMessageConversation -import org.mariotaku.twidere.model.ParcelableUser -import org.mariotaku.twidere.model.UserKey -import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask -import org.mariotaku.twidere.util.DataStoreUtils - -/** - * Created by mariotaku on 2017/2/25. - */ - -class AddParticipantsTask( - context: Context, - val accountKey: UserKey, - val conversationId: String, - val participants: Collection -) : ExceptionHandlingAbstractTask Unit)?>(context) { - - private val profileImageSize: String = context.getString(R.string.profile_image_size) - - override val exceptionClass = MicroBlogException::class.java - - override fun onExecute(params: Unit?): Boolean { - val account = AccountManager.get(context).getDetailsOrThrow(accountKey, true) - val conversation = DataStoreUtils.findMessageConversation(context, accountKey, conversationId) - if (conversation != null && conversation.is_temp) { - val addData = GetMessagesTask.DatabaseUpdateData(listOf(conversation), emptyList()) - conversation.addParticipants(participants) - GetMessagesTask.storeMessages(context, addData, account, showNotification = false) - // Don't finish too fast - Thread.sleep(300L) - return true - } - - val addData = requestAddParticipants(account, conversation) - GetMessagesTask.storeMessages(context, addData, account, showNotification = false) - return true - } - - override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Boolean?, exception: MicroBlogException?) { - callback?.invoke(result ?: false) - } - - private fun requestAddParticipants(account: AccountDetails, conversation: ParcelableMessageConversation?): - GetMessagesTask.DatabaseUpdateData { - when (account.type) { - AccountType.TWITTER -> { - if (account.isOfficial(context)) { - val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java) - val ids = participants.mapToArray { it.key.id } - val response = microBlog.addParticipants(conversationId, ids) - if (conversation != null) { - conversation.addParticipants(participants) - return GetMessagesTask.DatabaseUpdateData(listOf(conversation), emptyList()) - } - return GetMessagesTask.createDatabaseUpdateData(context, account, response, - profileImageSize) - } - } - - } - throw MicroBlogException("Adding participants is not supported") - } - -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/BatchMarkMessageReadTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/BatchMarkMessageReadTask.kt deleted file mode 100644 index d0bb5ffff..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/BatchMarkMessageReadTask.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2017 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.task.twitter.message - -import android.accounts.AccountManager -import android.content.Context -import org.mariotaku.ktextension.forEachRow -import org.mariotaku.library.objectcursor.ObjectCursor -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.sqliteqb.library.Columns -import org.mariotaku.sqliteqb.library.Expression -import org.mariotaku.sqliteqb.library.Table -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.ParcelableMessageConversation -import org.mariotaku.twidere.model.UserKey -import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent -import org.mariotaku.twidere.model.util.AccountUtils -import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations -import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask -import org.mariotaku.twidere.util.TwidereQueryBuilder -import org.mariotaku.twidere.util.getUnreadMessagesEntriesCursorReference - -/** - * Created by mariotaku on 2017/2/16. - */ - -class BatchMarkMessageReadTask( - context: Context, - val accountKey: UserKey, - val markTimestampBefore: Long -) : ExceptionHandlingAbstractTask(context) { - - override val exceptionClass = MicroBlogException::class.java - - override fun onExecute(params: Unit?): Boolean { - val cr = context.contentResolver - val projection = (Conversations.COLUMNS + Conversations.UNREAD_COUNT).map { - TwidereQueryBuilder.mapConversationsProjection(it) - }.toTypedArray() - - val unreadWhere = Expression.greaterThan(Columns.Column(Table(Conversations.TABLE_NAME), - Conversations.LAST_READ_TIMESTAMP), markTimestampBefore) - val unreadHaving = Expression.greaterThan(Conversations.UNREAD_COUNT, 0) - - val cRef = cr.getUnreadMessagesEntriesCursorReference(projection, arrayOf(accountKey), - unreadWhere, null, unreadHaving, null) ?: return false - val account = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?: - throw MicroBlogException("No account") - val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java) - cRef.use { (cur) -> - val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) - cur.forEachRow { c, _ -> - val conversation = indices.newObject(c) - try { - val lastReadEvent = MarkMessageReadTask.performMarkRead(context, microBlog, - account, conversation) ?: return@forEachRow false - MarkMessageReadTask.updateLocalLastRead(cr, account.key, conversation.id, - lastReadEvent) - return@forEachRow true - } catch (e: MicroBlogException) { - return@forEachRow false - } - } - } - return true - } - - override fun onSucceed(callback: Unit?, result: Boolean) { - bus.post(UnreadCountUpdatedEvent(-1)) - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt deleted file mode 100644 index 5cd678c6c..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2017 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.task.twitter.message - -import android.accounts.AccountManager -import android.content.ContentResolver -import android.content.ContentValues -import android.content.Context -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.sqliteqb.library.Expression -import org.mariotaku.sqliteqb.library.OrderBy -import org.mariotaku.twidere.annotation.AccountType -import org.mariotaku.twidere.extension.model.isOfficial -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.extension.model.timestamp -import org.mariotaku.twidere.extension.queryOne -import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableMessage -import org.mariotaku.twidere.model.ParcelableMessageConversation -import org.mariotaku.twidere.model.UserKey -import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent -import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras -import org.mariotaku.twidere.model.util.AccountUtils -import org.mariotaku.twidere.provider.TwidereDataStore.Messages -import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations -import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask -import org.mariotaku.twidere.task.twitter.message.SendMessageTask.Companion.TEMP_CONVERSATION_ID_PREFIX -import org.mariotaku.twidere.util.DataStoreUtils - -/** - * Created by mariotaku on 2017/2/16. - */ - -class MarkMessageReadTask( - context: Context, - val accountKey: UserKey, - val conversationId: String -) : ExceptionHandlingAbstractTask(context) { - - override val exceptionClass = MicroBlogException::class.java - - override fun onExecute(params: Unit?): Boolean { - if (conversationId.startsWith(TEMP_CONVERSATION_ID_PREFIX)) return true - val account = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?: - throw MicroBlogException("No account") - val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java) - val conversation = DataStoreUtils.findMessageConversation(context, accountKey, conversationId) - val lastReadEvent = conversation?.let { - return@let performMarkRead(context, microBlog, account, conversation) - } ?: return false - updateLocalLastRead(context.contentResolver, accountKey, conversationId, lastReadEvent) - return true - } - - override fun onSucceed(callback: Unit?, result: Boolean) { - bus.post(UnreadCountUpdatedEvent(-1)) - } - - - companion object { - - @Throws(MicroBlogException::class) - internal fun performMarkRead(context: Context, microBlog: MicroBlog, account: AccountDetails, - conversation: ParcelableMessageConversation): Pair? { - val cr = context.contentResolver - when (account.type) { - AccountType.TWITTER -> { - if (account.isOfficial(context)) { - val event = (conversation.conversation_extras as? TwitterOfficialConversationExtras)?.maxReadEvent ?: run { - val message = cr.findRecentMessage(account.key, conversation.id) ?: return null - return@run Pair(message.id, message.timestamp) - } - if (conversation.last_read_timestamp > event.second) { - // Local is newer, ignore network request - return event - } - if (microBlog.markDmRead(conversation.id, event.first).isSuccessful) { - return event - } - } - } - } - val message = cr.findRecentMessage(account.key, conversation.id) ?: return null - return Pair(message.id, message.timestamp) - } - - internal fun updateLocalLastRead(cr: ContentResolver, accountKey: UserKey, - conversationId: String, lastRead: Pair) { - val values = ContentValues() - values.put(Conversations.LAST_READ_ID, lastRead.first) - values.put(Conversations.LAST_READ_TIMESTAMP, lastRead.second) - val updateWhere = Expression.and(Expression.equalsArgs(Conversations.ACCOUNT_KEY), - Expression.equalsArgs(Conversations.CONVERSATION_ID), - Expression.lesserThan(Conversations.LAST_READ_TIMESTAMP, lastRead.second)).sql - val updateWhereArgs = arrayOf(accountKey.toString(), conversationId) - cr.update(Conversations.CONTENT_URI, values, updateWhere, updateWhereArgs) - } - - private fun ContentResolver.findRecentMessage(accountKey: UserKey, conversationId: String): ParcelableMessage? { - val where = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY), - Expression.equalsArgs(Messages.CONVERSATION_ID)).sql - val whereArgs = arrayOf(accountKey.toString(), conversationId) - return queryOne(Messages.CONTENT_URI, Messages.COLUMNS, where, whereArgs, - OrderBy(Messages.LOCAL_TIMESTAMP, false).sql, ParcelableMessage::class.java) - } - - private val TwitterOfficialConversationExtras.maxReadEvent: Pair? - get() { - val id = maxEntryId ?: return null - if (maxEntryTimestamp < 0) return null - return Pair(id, maxEntryTimestamp) - } - - } -}