This commit is contained in:
Mariotaku Lee 2017-04-30 00:34:26 +08:00
parent 1512f5afe6
commit 435bbdb79b
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
12 changed files with 204 additions and 166 deletions

View File

@ -0,0 +1,26 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.constant
/**
* Created by mariotaku on 2017/4/29.
*/
const val TWITTER_ERROR_ALREADY_FAVORITED = 139
const val TWITTER_ERROR_ALREADY_RETWEETED = 327

View File

@ -41,4 +41,8 @@ fun <T> ContentResolver.queryOne(uri: Uri, projection: Array<String>?, selection
val indices = ObjectCursor.indicesFrom(cursor, cls)
return@useCursor indices.newObject(cursor)
}
}
fun <T : Any> ContentResolver.insertOne(uri: Uri, obj: T, cls: Class<T> = obj.javaClass): Uri? {
return this.insert(uri, ObjectCursor.valuesCreatorFrom(cls).create(obj))
}

View File

@ -42,7 +42,6 @@ import org.mariotaku.twidere.loader.AccountDetailsLoader
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.AccountPreferences
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.IntentUtils
@ -194,20 +193,12 @@ class AccountsManagerFragment : BaseFragment(), LoaderManager.LoaderCallbacks<Li
val statusValues = ContentValues().apply {
put(Statuses.ACCOUNT_COLOR, details.color)
}
val activityValues = ContentValues().apply {
put(Activities.ACCOUNT_COLOR, details.color)
}
val statusesWhere = Expression.equalsArgs(Statuses.ACCOUNT_KEY)
val statusesWhereArgs = arrayOf(details.key.toString())
val activitiesWhere = Expression.equalsArgs(Activities.ACCOUNT_KEY)
val activitiesWhereArgs = arrayOf(details.key.toString())
DataStoreUtils.STATUSES_URIS.forEach { uri ->
DataStoreUtils.STATUSES_ACTIVITIES_URIS.forEach { uri ->
resolver.update(uri, statusValues, statusesWhere.sql, statusesWhereArgs)
}
DataStoreUtils.ACTIVITIES_URIS.forEach { uri ->
resolver.update(uri, activityValues, activitiesWhere.sql, activitiesWhereArgs)
}
}
/**

View File

@ -2103,10 +2103,11 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
Expression.equalsArgs(Statuses.RETWEET_ID)))
val statusWhereArgs = arrayOf(accountKey.toString(), statusId, statusId)
cr.update(Statuses.CONTENT_URI, countValues, statusWhere.sql, statusWhereArgs)
cr.updateActivityStatus(accountKey, statusId) { activity ->
activity.favorite_count = activitySummary.favoriteCount
activity.reply_count = activitySummary.replyCount
activity.retweet_count = activitySummary.retweetCount
cr.updateStatusInfo(DataStoreUtils.STATUSES_ACTIVITIES_URIS, Statuses.COLUMNS,
accountKey, statusId, ParcelableStatus::class.java) { item ->
item.favorite_count = activitySummary.favoriteCount
item.reply_count = activitySummary.replyCount
item.retweet_count = activitySummary.retweetCount
}
val pStatus = status.toParcelable(details)
cr.insert(CachedStatuses.CONTENT_URI, ObjectCursor

View File

@ -22,12 +22,17 @@ package org.mariotaku.twidere.task
import android.accounts.AccountManager
import android.content.Context
import android.widget.Toast
import org.mariotaku.ktextension.toLongOr
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.twidere.exception.AccountNotFoundException
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.insertOne
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
/**
* Created by mariotaku on 2017/4/20.
@ -41,13 +46,32 @@ abstract class AbsAccountRequestTask<Params, Result, Callback>(context: Context,
val am = AccountManager.get(context)
val account = accountKey?.let { AccountUtils.getAccountDetails(am, it, true) } ?:
throw AccountNotFoundException()
val draft = createDraft()
var draftId = -1L
if (draft != null) {
val uri = context.contentResolver.insertOne(Drafts.CONTENT_URI, draft)
draftId = uri?.lastPathSegment.toLongOr(-1)
}
if (draftId != -1L) {
microBlogWrapper.addSendingDraftId(draftId)
}
try {
val result = onExecute(account, params)
onCleanup(account, params, result, null)
if (draftId != -1L) {
UpdateStatusTask.deleteDraft(context, draftId)
}
return result
} catch (e: MicroBlogException) {
onCleanup(account, params, null, e)
if (draftId != 1L && deleteDraftOnException(account, params, e)) {
UpdateStatusTask.deleteDraft(context, draftId)
}
throw e
} finally {
if (draftId != -1L) {
microBlogWrapper.removeSendingDraftId(draftId)
}
}
}
@ -64,6 +88,10 @@ abstract class AbsAccountRequestTask<Params, Result, Callback>(context: Context,
protected open fun onCleanup(account: AccountDetails, params: Params, result: Result) {}
protected open fun onCleanup(account: AccountDetails, params: Params, exception: MicroBlogException) {}
protected open fun createDraft(): Draft? = null
protected open fun deleteDraftOnException(account: AccountDetails, params: Params, exception: MicroBlogException): Boolean = false
override fun onException(callback: Callback?, exception: MicroBlogException) {
Toast.makeText(context, exception.getErrorMessage(context), Toast.LENGTH_SHORT).show()
}

View File

@ -1,14 +1,16 @@
package org.mariotaku.twidere.task
import android.content.ContentValues
import android.content.Context
import android.widget.Toast
import org.apache.commons.collections.primitives.ArrayIntList
import org.mariotaku.kpreferences.get
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.TWITTER_ERROR_ALREADY_FAVORITED
import org.mariotaku.twidere.constant.iWantMyStarsBackKey
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
@ -25,7 +27,7 @@ import org.mariotaku.twidere.task.twitter.UpdateStatusTask
import org.mariotaku.twidere.util.AsyncTwitterWrapper.Companion.calculateHashCode
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.updateActivityStatus
import org.mariotaku.twidere.util.updateStatusInfo
/**
* Created by mariotaku on 2017/2/7.
@ -34,59 +36,34 @@ class CreateFavoriteTask(context: Context, accountKey: UserKey, private val stat
AbsAccountRequestTask<Any?, ParcelableStatus, Any?>(context, accountKey) {
private val statusId = status.id
override fun onExecute(account: AccountDetails, params: Any?): ParcelableStatus {
val draftId = UpdateStatusTask.saveDraft(context, Draft.Action.FAVORITE) {
this@saveDraft.account_keys = arrayOf(accountKey)
this@saveDraft.action_extras = StatusObjectActionExtras().apply {
this@apply.status = this@CreateFavoriteTask.status
}
}
microBlogWrapper.addSendingDraftId(draftId)
val resolver = context.contentResolver
try {
val result = when (account.type) {
AccountType.FANFOU -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.createFanfouFavorite(statusId).toParcelable(account)
}
AccountType.MASTODON -> {
val mastodon = account.newMicroBlogInstance(context, cls = Mastodon::class.java)
mastodon.favouriteStatus(statusId).toParcelable(account)
}
else -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.createFavorite(statusId).toParcelable(account)
}
val result = when (account.type) {
AccountType.FANFOU -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.createFanfouFavorite(statusId).toParcelable(account)
}
Utils.setLastSeen(context, result.mentions, System.currentTimeMillis())
val values = ContentValues()
values.put(Statuses.IS_FAVORITE, true)
values.put(Statuses.REPLY_COUNT, result.reply_count)
values.put(Statuses.RETWEET_COUNT, result.retweet_count)
values.put(Statuses.FAVORITE_COUNT, result.favorite_count)
val statusWhere = Expression.and(
Expression.equalsArgs(Statuses.ACCOUNT_KEY),
Expression.or(
Expression.equalsArgs(Statuses.ID),
Expression.equalsArgs(Statuses.RETWEET_ID)
)
).sql
val statusWhereArgs = arrayOf(account.key.toString(), statusId, statusId)
for (uri in DataStoreUtils.STATUSES_URIS) {
resolver.update(uri, values, statusWhere, statusWhereArgs)
AccountType.MASTODON -> {
val mastodon = account.newMicroBlogInstance(context, cls = Mastodon::class.java)
mastodon.favouriteStatus(statusId).toParcelable(account)
}
resolver.updateActivityStatus(account.key, statusId) { activity ->
if (result.id != activity.id) return@updateActivityStatus
activity.is_favorite = true
activity.reply_count = result.reply_count
activity.retweet_count = result.retweet_count
activity.favorite_count = result.favorite_count
else -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.createFavorite(statusId).toParcelable(account)
}
UpdateStatusTask.deleteDraft(context, draftId)
return result
} finally {
microBlogWrapper.removeSendingDraftId(draftId)
}
Utils.setLastSeen(context, result.mentions, System.currentTimeMillis())
resolver.updateStatusInfo(DataStoreUtils.STATUSES_ACTIVITIES_URIS, Statuses.COLUMNS,
account.key, statusId, ParcelableStatus::class.java) { status ->
if (result.id != status.id) return@updateStatusInfo
status.is_favorite = true
status.reply_count = result.reply_count
status.retweet_count = result.retweet_count
status.favorite_count = result.favorite_count
}
return result
}
override fun beforeExecute() {
@ -104,6 +81,13 @@ class CreateFavoriteTask(context: Context, accountKey: UserKey, private val stat
if (result != null) {
taskEvent.status = result
taskEvent.isSucceeded = true
if (preferences[iWantMyStarsBackKey]) {
Toast.makeText(context, R.string.message_toast_status_favorited,
Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, R.string.message_toast_status_liked,
Toast.LENGTH_SHORT).show()
}
} else {
taskEvent.isSucceeded = false
Toast.makeText(context, exception?.getErrorMessage(context), Toast.LENGTH_SHORT).show()
@ -112,6 +96,28 @@ class CreateFavoriteTask(context: Context, accountKey: UserKey, private val stat
bus.post(StatusListChangedEvent())
}
override fun onCleanup(account: AccountDetails, params: Any?, exception: MicroBlogException) {
if (exception.errorCode == TWITTER_ERROR_ALREADY_FAVORITED) {
val resolver = context.contentResolver
resolver.updateStatusInfo(DataStoreUtils.STATUSES_ACTIVITIES_URIS, Statuses.COLUMNS,
account.key, statusId, ParcelableStatus::class.java) { status ->
if (statusId != status.id) return@updateStatusInfo
status.is_favorite = true
}
}
}
override fun createDraft() = UpdateStatusTask.createDraft(Draft.Action.FAVORITE) {
account_keys = arrayOf(accountKey)
action_extras = StatusObjectActionExtras().also { extras ->
extras.status = this@CreateFavoriteTask.status
}
}
override fun deleteDraftOnException(account: AccountDetails, params: Any?, exception: MicroBlogException): Boolean {
return exception.errorCode == TWITTER_ERROR_ALREADY_FAVORITED
}
companion object {

View File

@ -17,7 +17,8 @@ import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.event.FriendshipTaskEvent
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.Utils
@ -53,7 +54,7 @@ open class CreateUserBlockTask(
override fun succeededWorker(details: AccountDetails, args: Arguments, user: ParcelableUser) {
val resolver = context.contentResolver
Utils.setLastSeen(context, args.userKey, -1)
for (uri in DataStoreUtils.STATUSES_URIS) {
for (uri in DataStoreUtils.STATUSES_ACTIVITIES_URIS) {
val where = Expression.and(
Expression.equalsArgs(Statuses.ACCOUNT_KEY),
Expression.equalsArgs(Statuses.USER_KEY)
@ -61,14 +62,6 @@ open class CreateUserBlockTask(
val whereArgs = arrayOf(args.accountKey.toString(), args.userKey.toString())
resolver.delete(uri, where.sql, whereArgs)
}
for (uri in DataStoreUtils.ACTIVITIES_URIS) {
val where = Expression.and(
Expression.equalsArgs(Activities.ACCOUNT_KEY),
Expression.equalsArgs(Activities.USER_KEY)
)
val whereArgs = arrayOf(args.accountKey.toString(), args.userKey.toString())
resolver.delete(uri, where.sql, whereArgs)
}
// I bet you don't want to see this user in your auto complete list.
val values = ContentValues()
values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString())

View File

@ -1,13 +1,11 @@
package org.mariotaku.twidere.task
import android.content.ContentValues
import android.content.Context
import android.widget.Toast
import org.apache.commons.collections.primitives.ArrayIntList
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.getErrorMessage
@ -23,7 +21,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.AsyncTwitterWrapper.Companion.calculateHashCode
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.updateActivityStatus
import org.mariotaku.twidere.util.updateStatusInfo
/**
* Created by mariotaku on 2017/2/7.
@ -50,26 +48,12 @@ class DestroyFavoriteTask(
}
}
val values = ContentValues()
values.put(Statuses.IS_FAVORITE, false)
values.put(Statuses.FAVORITE_COUNT, result.favorite_count - 1)
values.put(Statuses.RETWEET_COUNT, result.retweet_count)
values.put(Statuses.REPLY_COUNT, result.reply_count)
val where = Expression.and(Expression.equalsArgs(Statuses.ACCOUNT_KEY),
Expression.or(Expression.equalsArgs(Statuses.ID),
Expression.equalsArgs(Statuses.RETWEET_ID)))
val whereArgs = arrayOf(accountKey.toString(), statusId, statusId)
for (uri in DataStoreUtils.STATUSES_URIS) {
resolver.update(uri, values, where.sql, whereArgs)
}
resolver.updateActivityStatus(account.key, statusId) { activity ->
if (result.id != activity.id) return@updateActivityStatus
activity.is_favorite = false
activity.reply_count = result.reply_count
activity.retweet_count = result.retweet_count
activity.favorite_count = result.favorite_count - 1
resolver.updateStatusInfo(DataStoreUtils.STATUSES_ACTIVITIES_URIS, Statuses.COLUMNS,
account.key, statusId, ParcelableStatus::class.java) { item ->
item.is_favorite = false
item.reply_count = result.reply_count
item.retweet_count = result.retweet_count
item.favorite_count = result.favorite_count - 1
}
return result

View File

@ -1,14 +1,15 @@
package org.mariotaku.twidere.task
import android.content.ContentValues
import android.content.Context
import android.widget.Toast
import org.apache.commons.collections.primitives.ArrayIntList
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.TWITTER_ERROR_ALREADY_FAVORITED
import org.mariotaku.twidere.constant.TWITTER_ERROR_ALREADY_RETWEETED
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
@ -26,7 +27,7 @@ import org.mariotaku.twidere.task.twitter.UpdateStatusTask
import org.mariotaku.twidere.util.AsyncTwitterWrapper
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.updateActivityStatus
import org.mariotaku.twidere.util.updateStatusInfo
/**
* Retweet status
@ -42,56 +43,33 @@ class RetweetStatusTask(
private val statusId = status.id
override fun onExecute(account: AccountDetails, params: Any?): ParcelableStatus {
val draftId = UpdateStatusTask.saveDraft(context, Draft.Action.RETWEET) {
this@saveDraft.account_keys = arrayOf(accountKey)
this@saveDraft.action_extras = StatusObjectActionExtras().apply {
this@apply.status = this@RetweetStatusTask.status
}
}
microBlogWrapper.addSendingDraftId(draftId)
val resolver = context.contentResolver
try {
val result = when (account.type) {
AccountType.MASTODON -> {
val mastodon = account.newMicroBlogInstance(context, cls = Mastodon::class.java)
mastodon.reblogStatus(statusId).toParcelable(account)
}
else -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.retweetStatus(statusId).toParcelable(account)
}
val result = when (account.type) {
AccountType.MASTODON -> {
val mastodon = account.newMicroBlogInstance(context, cls = Mastodon::class.java)
mastodon.reblogStatus(statusId).toParcelable(account)
}
ParcelableStatusUtils.updateExtraInformation(result, account)
Utils.setLastSeen(context, result.mentions, System.currentTimeMillis())
val values = ContentValues()
values.put(Statuses.MY_RETWEET_ID, result.id)
values.put(Statuses.REPLY_COUNT, result.reply_count)
values.put(Statuses.RETWEET_COUNT, result.retweet_count)
values.put(Statuses.FAVORITE_COUNT, result.favorite_count)
val where = Expression.or(
Expression.equalsArgs(Statuses.ID),
Expression.equalsArgs(Statuses.RETWEET_ID)
)
val whereArgs = arrayOf(statusId, statusId)
for (uri in DataStoreUtils.STATUSES_URIS) {
resolver.update(uri, values, where.sql, whereArgs)
else -> {
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
microBlog.retweetStatus(statusId).toParcelable(account)
}
resolver.updateActivityStatus(account.key, statusId) { activity ->
if (statusId != activity.id && statusId != activity.retweet_id &&
statusId != activity.my_retweet_id) {
return@updateActivityStatus
}
activity.my_retweet_id = result.id
activity.reply_count = result.reply_count
activity.retweet_count = result.retweet_count
activity.favorite_count = result.favorite_count
}
UpdateStatusTask.deleteDraft(context, draftId)
return result
} finally {
microBlogWrapper.removeSendingDraftId(draftId)
}
ParcelableStatusUtils.updateExtraInformation(result, account)
Utils.setLastSeen(context, result.mentions, System.currentTimeMillis())
resolver.updateStatusInfo(DataStoreUtils.STATUSES_ACTIVITIES_URIS, Statuses.COLUMNS,
account.key, statusId, ParcelableStatus::class.java) { status ->
if (statusId != status.id && statusId != status.retweet_id &&
statusId != status.my_retweet_id) {
return@updateStatusInfo
}
status.my_retweet_id = result.id
status.retweeted = true
status.reply_count = result.reply_count
status.retweet_count = result.retweet_count
status.favorite_count = result.favorite_count
}
return result
}
override fun beforeExecute() {
@ -106,13 +84,38 @@ class RetweetStatusTask(
creatingRetweetIds.removeElement(AsyncTwitterWrapper.calculateHashCode(accountKey, statusId))
if (result != null) {
bus.post(StatusRetweetedEvent(result))
Toast.makeText(context, R.string.message_toast_status_retweeted, Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, exception?.getErrorMessage(context), Toast.LENGTH_SHORT).show()
}
}
override fun onCleanup(account: AccountDetails, params: Any?, exception: MicroBlogException) {
if (exception.errorCode == TWITTER_ERROR_ALREADY_FAVORITED) {
val resolver = context.contentResolver
resolver.updateStatusInfo(DataStoreUtils.STATUSES_URIS, Statuses.COLUMNS, account.key,
statusId, ParcelableStatus::class.java) { status ->
status.retweeted = true
}
}
}
override fun createDraft() = UpdateStatusTask.createDraft(Draft.Action.RETWEET) {
account_keys = arrayOf(accountKey)
action_extras = StatusObjectActionExtras().also { extras ->
extras.status = this@RetweetStatusTask.status
}
}
override fun deleteDraftOnException(account: AccountDetails, params: Any?, exception: MicroBlogException): Boolean {
return exception.errorCode == TWITTER_ERROR_ALREADY_RETWEETED
}
companion object {
private val creatingRetweetIds = ArrayIntList()
fun isCreatingRetweet(accountKey: UserKey?, statusId: String?): Boolean {
return creatingRetweetIds.contains(AsyncTwitterWrapper.calculateHashCode(accountKey, statusId))
}

View File

@ -7,6 +7,7 @@ import android.content.Context
import android.content.SharedPreferences
import android.database.Cursor
import android.net.Uri
import android.provider.BaseColumns
import android.support.annotation.WorkerThread
import android.support.v4.util.LongSparseArray
import org.mariotaku.kpreferences.get
@ -160,7 +161,8 @@ fun ContentResolver.deleteActivityStatus(accountKey: UserKey, statusId: String,
}
for (uri in ACTIVITIES_URIS) {
delete(uri, deleteWhere, deleteWhereArgs)
updateActivity(uri, updateWhere, updateWhereArgs) { activity ->
updateItems(uri, Activities.COLUMNS, updateWhere, updateWhereArgs,
ParcelableActivity::class.java) { activity ->
activity.my_retweet_id = null
if (statusId == activity.id || statusId == activity.retweet_id ||
statusId == activity.my_retweet_id) {
@ -175,8 +177,8 @@ fun ContentResolver.deleteActivityStatus(accountKey: UserKey, statusId: String,
}
}
fun ContentResolver.updateActivityStatus(accountKey: UserKey, statusId: String,
action: (ParcelableActivity) -> Unit) {
fun <T : ParcelableStatus> ContentResolver.updateStatusInfo(uris: Array<Uri>, columns: Array<String>?,
accountKey: UserKey, statusId: String, cls: Class<T>, action: (T) -> Unit) {
val activityWhere = Expression.and(
Expression.equalsArgs(Activities.ACCOUNT_KEY),
Expression.or(
@ -185,25 +187,24 @@ fun ContentResolver.updateActivityStatus(accountKey: UserKey, statusId: String,
)
).sql
val activityWhereArgs = arrayOf(accountKey.toString(), statusId, statusId)
for (uri in ACTIVITIES_URIS) {
updateActivity(uri, activityWhere, activityWhereArgs, action)
for (uri in uris) {
updateItems(uri, columns, activityWhere, activityWhereArgs, cls, action)
}
}
@WorkerThread
fun ContentResolver.updateActivity(uri: Uri, where: String?,
whereArgs: Array<String>?, action: (ParcelableActivity) -> Unit) {
val c = query(uri, Activities.COLUMNS, where, whereArgs, null) ?: return
fun <T> ContentResolver.updateItems(uri: Uri, columns: Array<String>?, where: String?,
whereArgs: Array<String>?, cls: Class<T>, action: (T) -> Unit) {
val c = query(uri, columns, where, whereArgs, null) ?: return
val values = LongSparseArray<ContentValues>()
try {
val ci = ObjectCursor.indicesFrom(c, ParcelableActivity::class.java)
val vc = ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java)
val ci = ObjectCursor.indicesFrom(c, cls)
val vc = ObjectCursor.valuesCreatorFrom(cls)
c.moveToFirst()
while (!c.isAfterLast) {
val activity = ci.newObject(c)
action(activity)
values.put(activity._id, vc.create(activity))
val item = ci.newObject(c)
action(item)
values.put(c.getLong(ci[BaseColumns._ID]), vc.create(item))
c.moveToNext()
}
} catch (e: IOException) {
@ -212,7 +213,7 @@ fun ContentResolver.updateActivity(uri: Uri, where: String?,
c.close()
}
for (i in 0 until values.size()) {
val updateWhere = Expression.equals(Activities._ID, values.keyAt(i)).sql
val updateWhere = Expression.equals(BaseColumns._ID, values.keyAt(i)).sql
update(uri, values.valueAt(i), updateWhere, null)
}
}

View File

@ -67,9 +67,12 @@ import java.util.*
object DataStoreUtils {
val STATUSES_URIS = arrayOf(Statuses.CONTENT_URI, CachedStatuses.CONTENT_URI)
val CACHE_URIS = arrayOf(CachedUsers.CONTENT_URI, CachedStatuses.CONTENT_URI, CachedHashtags.CONTENT_URI, CachedTrends.Local.CONTENT_URI)
val CACHE_URIS = arrayOf(CachedUsers.CONTENT_URI, CachedStatuses.CONTENT_URI,
CachedHashtags.CONTENT_URI, CachedTrends.Local.CONTENT_URI)
val MESSAGES_URIS = arrayOf(Messages.CONTENT_URI, Conversations.CONTENT_URI)
val ACTIVITIES_URIS = arrayOf(Activities.AboutMe.CONTENT_URI)
val STATUSES_ACTIVITIES_URIS = arrayOf(Statuses.CONTENT_URI, CachedStatuses.CONTENT_URI,
Activities.AboutMe.CONTENT_URI)
private val CONTENT_PROVIDER_URI_MATCHER = UriMatcher(UriMatcher.NO_MATCH)
@ -765,7 +768,7 @@ object DataStoreUtils {
updateWhere = Expression.equalsArgs(Statuses.MY_RETWEET_ID).sql
updateWhereArgs = arrayOf(statusId)
}
for (uri in STATUSES_URIS) {
for (uri in STATUSES_ACTIVITIES_URIS) {
cr.delete(uri, deleteWhere, deleteWhereArgs)
if (status != null) {
val values = ContentValues()

View File

@ -419,14 +419,13 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
if (twitter.isDestroyingStatus(status.account_key, status.my_retweet_id)) {
retweetIcon.isActivated = false
retweetCount = Math.max(0, status.retweet_count - 1)
} else {
val creatingRetweet = RetweetStatusTask.isCreatingRetweet(status.account_key, status.id)
retweetIcon.isActivated = creatingRetweet || status.retweeted ||
Utils.isMyRetweet(status.account_key, status.retweeted_by_user_key,
status.my_retweet_id)
retweetCount = status.retweet_count + if (creatingRetweet) 1 else 0
}
retweetCount = status.retweet_count
if (retweetCount > 0) {
retweetCountView.text = UnitConvertUtils.calculateProperCount(retweetCount)
@ -437,12 +436,11 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
}
if (DestroyFavoriteTask.isDestroyingFavorite(status.account_key, status.id)) {
favoriteIcon.isActivated = false
favoriteCount = Math.max(0, status.favorite_count - 1)
} else {
val creatingFavorite = CreateFavoriteTask.isCreatingFavorite(status.account_key, status.id)
favoriteIcon.isActivated = creatingFavorite || status.is_favorite
favoriteCount = status.favorite_count + if (creatingFavorite) 1 else 0
}
favoriteCount = status.favorite_count
if (favoriteCount > 0) {
favoriteCountView.text = UnitConvertUtils.calculateProperCount(favoriteCount)
favoriteCountView.visibility = View.VISIBLE