improved status conversation load

This commit is contained in:
Mariotaku Lee 2017-02-10 19:55:00 +08:00
parent 48c7c5fa99
commit 7e577b5957
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 55 additions and 47 deletions

View File

@ -20,7 +20,6 @@
package org.mariotaku.twidere.fragment
import android.accounts.AccountManager
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Rect
@ -310,7 +309,8 @@ abstract class AbsActivitiesFragment protected constructor() :
val accountIds = arrayOf(activity.account_key)
val maxIds = arrayOf(activity.min_position)
val maxSortIds = longArrayOf(activity.min_sort_position)
getActivities(BaseRefreshTaskParam(accountIds, maxIds, null, maxSortIds, null))
getActivities(BaseRefreshTaskParam(accountKeys = accountIds, maxIds = maxIds,
sinceIds = null, maxSortIds = maxSortIds, sinceSortIds = null))
}
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, position: Int) {

View File

@ -359,7 +359,8 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
val accountIds = arrayOf(status.account_key)
val maxIds = arrayOf<String?>(status.id)
val maxSortIds = longArrayOf(status.sort_id)
getStatuses(BaseRefreshTaskParam(accountIds, maxIds, null, maxSortIds, null))
getStatuses(BaseRefreshTaskParam(accountKeys = accountIds, maxIds = maxIds, sinceIds = null,
maxSortIds = maxSortIds, sinceSortIds = null))
}
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {

View File

@ -8,6 +8,7 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.sqliteqb.library.OrderBy
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.MessagesEntriesAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.extension.model.user
import org.mariotaku.twidere.loader.ObjectCursorLoader
@ -35,6 +36,7 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
adapter.listener = this
adapter.loadMoreSupportedPosition = ILoadMoreSupportAdapter.END
loaderManager.initLoader(0, null, this)
}
@ -70,6 +72,10 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment<MessagesEntri
return true
}
override fun onLoadMoreContents(position: Long) {
super.onLoadMoreContents(position)
}
override fun onConversationClick(position: Int) {
val conversation = adapter.getConversation(position) ?: return
IntentUtils.openMessageConversation(context, conversation.account_key, conversation.id)

View File

@ -155,7 +155,9 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
val loader = ConversationLoader(activity, status, sinceId, maxId, sinceSortId, maxSortId,
adapter.getData(), true, loadingMore)
// Setting comparator to null lets statuses sort ascending
loader.comparator = null
loader.comparator = Comparator { l, r ->
(l.sort_id - r.sort_id).toInt()
}
return loader
}
@ -1503,7 +1505,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override val lightFont: Boolean
override val mediaPreviewEnabled: Boolean
override val sensitiveContentEnabled: Boolean
private val mShowCardActions: Boolean
private val showCardActions: Boolean
override val useStarsForLikes: Boolean
private var mDetailMediaExpanded: Boolean = false
@ -1533,8 +1535,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private var data: List<ParcelableStatus>? = null
private var replyError: CharSequence? = null
private var conversationError: CharSequence? = null
private var mReplyStart: Int = 0
private var mShowingActionCardPosition: Int = 0
private var replyStart: Int = 0
private var showingActionCardPosition: Int = 0
init {
setHasStableIds(true)
@ -1555,7 +1557,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
linkHighlightingStyle = preferences[linkHighlightOptionKey]
mediaPreviewEnabled = preferences[mediaPreviewKey]
sensitiveContentEnabled = preferences.getBoolean(SharedPreferenceConstants.KEY_DISPLAY_SENSITIVE_CONTENTS, false)
mShowCardActions = !preferences[hideCardActionsKey]
showCardActions = !preferences[hideCardActionsKey]
useStarsForLikes = preferences[iWantMyStarsBackKey]
val listener = StatusAdapterLinkClickHandler<List<ParcelableStatus>>(context, preferences)
listener.setAdapter(this)
@ -1570,9 +1572,9 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
return data!![position - getIndexStart(ITEM_IDX_CONVERSATION)]
}
ITEM_IDX_REPLY -> {
if (data == null || mReplyStart < 0) return null
if (data == null || replyStart < 0) return null
return data!![position - getIndexStart(ITEM_IDX_CONVERSATION)
- getTypeCount(ITEM_IDX_CONVERSATION) - getTypeCount(ITEM_IDX_STATUS) + mReplyStart]
- getTypeCount(ITEM_IDX_CONVERSATION) - getTypeCount(ITEM_IDX_STATUS) + replyStart]
}
ITEM_IDX_STATUS -> {
return status
@ -1622,15 +1624,15 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
}
override fun isCardActionsShown(position: Int): Boolean {
if (position == RecyclerView.NO_POSITION) return mShowCardActions
return mShowCardActions || mShowingActionCardPosition == position
if (position == RecyclerView.NO_POSITION) return showCardActions
return showCardActions || showingActionCardPosition == position
}
override fun showCardActions(position: Int) {
if (mShowingActionCardPosition != RecyclerView.NO_POSITION) {
notifyItemChanged(mShowingActionCardPosition)
if (showingActionCardPosition != RecyclerView.NO_POSITION) {
notifyItemChanged(showingActionCardPosition)
}
mShowingActionCardPosition = position
showingActionCardPosition = position
if (position != RecyclerView.NO_POSITION) {
notifyItemChanged(position)
}
@ -1638,12 +1640,12 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
override fun setData(data: List<ParcelableStatus>?): Boolean {
val status = this.status ?: return false
val changed = !CompareUtils.objectEquals(data, data)
val changed = this.data != data
this.data = data
if (data == null || data.isEmpty()) {
setTypeCount(ITEM_IDX_CONVERSATION, 0)
setTypeCount(ITEM_IDX_REPLY, 0)
mReplyStart = -1
replyStart = -1
} else {
var sortId = status.sort_id
if (status.is_retweet) {
@ -1657,8 +1659,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
var conversationCount = 0
var replyCount = 0
var replyStart = -1
for (i in 0 until data.size) {
val item = data[i]
data.forEachIndexed { i, item ->
if (item.sort_id < sortId) {
conversationCount++
} else if (item.sort_id > sortId && status.id != item.id) {
@ -1670,7 +1671,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
}
setTypeCount(ITEM_IDX_CONVERSATION, conversationCount)
setTypeCount(ITEM_IDX_REPLY, replyCount)
mReplyStart = replyStart
this.replyStart = replyStart
}
notifyDataSetChanged()
updateItemDecoration()

View File

@ -7,15 +7,11 @@ open class BaseRefreshTaskParam(
override val accountKeys: Array<UserKey>,
override val maxIds: Array<String?>?,
override val sinceIds: Array<String?>?,
override val cursors: Array<String?>? = null,
override val maxSortIds: LongArray? = null,
override val sinceSortIds: LongArray? = null
) : RefreshTaskParam {
override var isLoadingMore: Boolean = false
override var shouldAbort: Boolean = false
override val hasMaxIds: Boolean
get() = maxIds != null
override val hasSinceIds: Boolean
get() = sinceIds != null
}

View File

@ -10,13 +10,20 @@ interface RefreshTaskParam {
val sinceIds: Array<String?>?
val cursors: Array<String?>?
val maxSortIds: LongArray?
val sinceSortIds: LongArray?
val hasMaxIds: Boolean
get() = maxIds != null
val hasSinceIds: Boolean
get() = sinceIds != null
val hasCursors: Boolean
get() = cursors != null
val isLoadingMore: Boolean

View File

@ -22,11 +22,8 @@ abstract class SimpleRefreshTaskParam : RefreshTaskParam {
override val sinceIds: Array<String?>?
get() = null
override val hasMaxIds: Boolean
get() = maxIds != null
override val hasSinceIds: Boolean
get() = sinceIds != null
override val cursors: Array<String?>?
get() = null
override val sinceSortIds: LongArray?
get() = null

View File

@ -20,7 +20,6 @@ import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
import org.mariotaku.twidere.model.util.ParcelableUserUtils
import org.mariotaku.twidere.model.util.UserKeyUtils
import org.mariotaku.twidere.provider.TwidereDataStore.AccountSupportColumns
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
import org.mariotaku.twidere.util.content.ContentResolverUtils
@ -37,7 +36,7 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
val details = getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
val microBlog = details.newMicroBlogInstance(context, true, cls = MicroBlog::class.java)
val messages = try {
getMessages(microBlog, details)
getMessages(microBlog, details, param, i)
} catch (e: MicroBlogException) {
return@forEachIndexed
}
@ -49,7 +48,7 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
callback?.invoke(true)
}
private fun getMessages(microBlog: MicroBlog, details: AccountDetails): GetMessagesData {
private fun getMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshTaskParam, index: Int): GetMessagesData {
when (details.type) {
AccountType.FANFOU -> {
// Use fanfou DM api
@ -58,32 +57,37 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
AccountType.TWITTER -> {
// Use official DM api
if (details.isOfficial(context)) {
return getTwitterOfficialMessages(microBlog, details)
return getTwitterOfficialMessages(microBlog, details, param, index)
}
}
}
// Use default method
return getDefaultMessages(microBlog, details)
return getDefaultMessages(microBlog, details, param, index)
}
private fun getFanfouMessages(microBlog: MicroBlog): GetMessagesData {
return GetMessagesData(emptyList(), emptyList())
}
private fun getTwitterOfficialMessages(microBlog: MicroBlog, details: AccountDetails): GetMessagesData {
return getDefaultMessages(microBlog, details)
private fun getTwitterOfficialMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshTaskParam, index: Int): GetMessagesData {
return getDefaultMessages(microBlog, details, param, index)
}
private fun getDefaultMessages(microBlog: MicroBlog, details: AccountDetails): GetMessagesData {
private fun getDefaultMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshTaskParam, index: Int): GetMessagesData {
val accountKey = details.key
val paging = Paging()
val received = microBlog.getDirectMessages(Paging().apply {
count(100)
})
val sent = microBlog.getSentDirectMessages(Paging().apply {
count(100)
})
val insertMessages = arrayListOf<ParcelableMessage>()
val conversations = hashMapOf<String, ParcelableMessageConversation>()
val received = microBlog.getDirectMessages(paging)
val sent = microBlog.getSentDirectMessages(paging)
val conversationIds = hashSetOf<String>()
received.forEach {
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
@ -135,10 +139,6 @@ class GetMessagesTask(context: Context) : BaseAbstractTask<RefreshTaskParam, Uni
private fun storeMessages(data: GetMessagesData, details: AccountDetails) {
val resolver = context.contentResolver
val where = Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY).sql
val whereArgs = arrayOf(details.key.toString())
resolver.delete(Messages.CONTENT_URI, where, whereArgs)
resolver.delete(Conversations.CONTENT_URI, where, whereArgs)
val conversationsValues = data.conversations.map {
val values = ParcelableMessageConversationValuesCreator.create(it)
if (it._id > 0) {