migrated status pagination

This commit is contained in:
Mariotaku Lee 2017-04-22 00:32:03 +08:00
parent 2308a6c291
commit 8fc93f1d2e
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
34 changed files with 344 additions and 338 deletions

View File

@ -136,6 +136,8 @@ public class Status {
@JsonField(name = "application")
Application application;
private long sortId = -1;
public String getId() {
return id;
}
@ -217,6 +219,21 @@ public class Status {
return application;
}
public long getSortId() {
if (sortId != -1) return sortId;
// Try use long id
try {
sortId = Long.parseLong(id);
} catch (NumberFormatException e) {
// Ignore
}
if (sortId == -1 && createdAt != null) {
// Try use timestamp
sortId = createdAt.getTime();
}
return sortId;
}
@Override
public String toString() {
return "Status{" +

View File

@ -160,12 +160,9 @@ public interface IntentConstants {
String EXTRA_LOCATION = "location";
String EXTRA_URL = "url";
String EXTRA_PROFILE_URL = "profile_url";
String EXTRA_NEXT_PAGE = "next_page";
String EXTRA_NEXT_PAGINATION = "next_pagination";
String EXTRA_PREV_PAGINATION = "prev_pagination";
String EXTRA_PAGINATION = "pagination";
String EXTRA_NEXT_CURSOR = "next_cursor";
String EXTRA_PREV_CURSOR = "prev_cursor";
String EXTRA_EXTRA_INTENT = "extra_intent";
String EXTRA_IS_MY_ACCOUNT = "is_my_account";
String EXTRA_TAB_TYPE = "tab_type";

View File

@ -42,6 +42,10 @@ public class CursorPagination implements Pagination, Parcelable {
return cursor;
}
public void setCursor(String cursor) {
this.cursor = cursor;
}
@Override
public void applyTo(Paging paging) {
paging.cursor(cursor);
@ -69,6 +73,14 @@ public class CursorPagination implements Pagination, Parcelable {
}
};
@Nullable
public static CursorPagination valueOf(String cursor) {
if (cursor == null) return null;
final CursorPagination pagination = new CursorPagination();
pagination.cursor = cursor;
return pagination;
}
@Nullable
public static CursorPagination valueOf(long cursor) {
if (cursor == 0) return null;

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.model.pagination;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
@ -35,6 +36,8 @@ public class SinceMaxPagination implements Pagination, Parcelable {
String sinceId;
String maxId;
long sinceSortId;
long maxSortId;
public String getSinceId() {
return sinceId;
@ -52,6 +55,22 @@ public class SinceMaxPagination implements Pagination, Parcelable {
this.maxId = maxId;
}
public long getSinceSortId() {
return sinceSortId;
}
public void setSinceSortId(long sinceSortId) {
this.sinceSortId = sinceSortId;
}
public long getMaxSortId() {
return maxSortId;
}
public void setMaxSortId(long maxSortId) {
this.maxSortId = maxSortId;
}
@Override
public void applyTo(Paging paging) {
if (sinceId != null) {
@ -72,6 +91,24 @@ public class SinceMaxPagination implements Pagination, Parcelable {
SinceMaxPaginationParcelablePlease.writeToParcel(this, dest, flags);
}
@Nullable
public static SinceMaxPagination sinceId(String sinceId, long sinceSortId) {
if (sinceId == null) return null;
SinceMaxPagination pagination = new SinceMaxPagination();
pagination.setSinceId(sinceId);
pagination.setSinceSortId(sinceSortId);
return pagination;
}
@Nullable
public static SinceMaxPagination maxId(String maxId, long maxSortId) {
if (maxId == null) return null;
SinceMaxPagination pagination = new SinceMaxPagination();
pagination.setMaxId(maxId);
pagination.setMaxSortId(maxSortId);
return pagination;
}
public static final Creator<SinceMaxPagination> CREATOR = new Creator<SinceMaxPagination>() {
public SinceMaxPagination createFromParcel(Parcel source) {
SinceMaxPagination target = new SinceMaxPagination();

View File

@ -148,8 +148,9 @@ class UserListSelectorActivity : BaseActivity(),
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUserList>> {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
val nextCursor = args.getLong(EXTRA_NEXT_CURSOR)
return UserListOwnershipsLoader(this, accountKey, userKey, null, adapter.all)
return UserListOwnershipsLoader(this, accountKey, userKey, null, adapter.all).apply {
pagination = args.getParcelable(EXTRA_PAGINATION)
}
}
override fun onLoaderReset(loader: Loader<List<ParcelableUserList>>?) {

View File

@ -0,0 +1,44 @@
/*
* 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.extension.model
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
val RefreshTaskParam.hasMaxIds: Boolean
get() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun RefreshTaskParam.getMaxId(index: Int): String? {
return (pagination?.get(index) as? SinceMaxPagination)?.maxId
}
fun RefreshTaskParam.getSinceId(index: Int): String? {
return (pagination?.get(index) as? SinceMaxPagination)?.sinceId
}
fun RefreshTaskParam.getMaxSortId(index: Int): Long {
return (pagination?.get(index) as? SinceMaxPagination)?.maxSortId ?: -1
}
fun RefreshTaskParam.getSinceSortId(index: Int): Long {
return (pagination?.get(index) as? SinceMaxPagination)?.sinceSortId ?: -1
}

View File

@ -38,6 +38,7 @@ fun Status.toParcelable(accountKey: UserKey): ParcelableStatus {
val extras = ParcelableStatus.Extras()
result.account_key = accountKey
result.id = id
result.sort_id = sortId
result.timestamp = createdAt?.time ?: 0
extras.summary_text = spoilerText

View File

@ -62,6 +62,7 @@ import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.analyzer.Share
import org.mariotaku.twidere.model.event.StatusListChangedEvent
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
import org.mariotaku.twidere.model.util.getActivityStatus
@ -305,10 +306,9 @@ abstract class AbsActivitiesFragment protected constructor() :
}
}
val accountKeys = arrayOf(activity.account_key)
val maxIds = arrayOf(activity.min_position)
val maxSortIds = longArrayOf(activity.min_sort_position)
getActivities(BaseRefreshTaskParam(accountKeys = accountKeys, maxIds = maxIds,
sinceIds = null, maxSortIds = maxSortIds, sinceSortIds = null).also {
val pagination = arrayOf(SinceMaxPagination.maxId(activity.min_position,
activity.min_sort_position))
getActivities(BaseRefreshTaskParam(accountKeys, pagination).also {
it.extraId = activity._id
})
}

View File

@ -57,6 +57,7 @@ import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.analyzer.Share
import org.mariotaku.twidere.model.event.StatusListChangedEvent
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.timeline.TimelineFilter
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
@ -351,10 +352,8 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
DebugLog.v(msg = "Load activity gap $status")
adapter.addGapLoadingId(ObjectId(status.account_key, status.id))
val accountKeys = arrayOf(status.account_key)
val maxIds = arrayOf<String?>(status.id)
val maxSortIds = longArrayOf(status.sort_id)
getStatuses(BaseRefreshTaskParam(accountKeys = accountKeys, maxIds = maxIds, sinceIds = null,
maxSortIds = maxSortIds, sinceSortIds = null))
val pagination = arrayOf(SinceMaxPagination.maxId(status.id, status.sort_id))
getStatuses(BaseRefreshTaskParam(accountKeys, pagination))
}
override fun onMediaClick(holder: IStatusViewHolder, view: View, current: ParcelableMedia,

View File

@ -44,6 +44,7 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.event.*
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.task.twitter.GetStatusesTask
@ -145,28 +146,22 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() {
super.onLoadMoreContents(position)
if (position == 0L) return
val contentUri = this.contentUri
getActivities(object : SimpleRefreshTaskParam() {
override val accountKeys: Array<UserKey> by lazy {
getActivities(object : RefreshTaskParam {
override val accountKeys by lazy {
this@CursorActivitiesFragment.accountKeys
}
override val maxIds: Array<String?>?
get() {
val context = context ?: return null
return DataStoreUtils.getRefreshOldestActivityMaxPositions(context, contentUri,
accountKeys.toNulls())
override val pagination by lazy {
val keys = accountKeys.toNulls()
val maxIds = DataStoreUtils.getRefreshOldestActivityMaxPositions(context, contentUri,
keys)
val maxSortIds = DataStoreUtils.getRefreshOldestActivityMaxSortPositions(context,
contentUri, keys)
return@lazy Array(keys.size) { idx ->
SinceMaxPagination.maxId(maxIds[idx], maxSortIds[idx])
}
override val maxSortIds: LongArray?
get() {
val context = context ?: return null
return DataStoreUtils.getRefreshOldestActivityMaxSortPositions(context,
contentUri, accountKeys.toNulls())
}
override val hasMaxIds: Boolean
get() = true
override val shouldAbort: Boolean
get() = context == null
})
@ -176,28 +171,22 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() {
override fun triggerRefresh(): Boolean {
super.triggerRefresh()
val contentUri = this.contentUri
getActivities(object : SimpleRefreshTaskParam() {
override val accountKeys: Array<UserKey> by lazy {
getActivities(object : RefreshTaskParam {
override val accountKeys by lazy {
this@CursorActivitiesFragment.accountKeys
}
override val sinceIds: Array<String?>?
get() {
val context = context ?: return null
return DataStoreUtils.getRefreshNewestActivityMaxPositions(context, contentUri,
accountKeys.toNulls())
override val pagination by lazy {
val keys = accountKeys.toNulls()
val sinceIds = DataStoreUtils.getRefreshNewestActivityMaxPositions(context,
contentUri, keys)
val sinceSortIds = DataStoreUtils.getRefreshNewestActivityMaxSortPositions(context,
contentUri, keys)
return@lazy Array(keys.size) { idx ->
SinceMaxPagination.sinceId(sinceIds[idx], sinceSortIds[idx])
}
override val sinceSortIds: LongArray?
get() {
val context = context ?: return null
return DataStoreUtils.getRefreshNewestActivityMaxSortPositions(context,
contentUri, accountKeys.toNulls())
}
override val hasSinceIds: Boolean
get() = true
override val shouldAbort: Boolean
get() = context == null
})

View File

@ -45,9 +45,10 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader
import org.mariotaku.twidere.model.ParameterizedExpression
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.SimpleRefreshTaskParam
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.*
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.twitter.GetStatusesTask
@ -181,44 +182,38 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
if (ILoadMoreSupportAdapter.START in position) return
super.onLoadMoreContents(position)
if (position == 0L) return
getStatuses(object : SimpleRefreshTaskParam() {
override val accountKeys: Array<UserKey> by lazy {
getStatuses(object : RefreshTaskParam {
override val accountKeys by lazy {
this@CursorStatusesFragment.accountKeys
}
override val maxIds: Array<String?>?
get() = getOldestStatusIds(accountKeys)
override val maxSortIds: LongArray?
get() {
val context = context ?: return null
return DataStoreUtils.getOldestStatusSortIds(context, contentUri,
accountKeys.toNulls())
override val pagination by lazy {
val keys = accountKeys.toNulls()
val maxIds = DataStoreUtils.getOldestStatusIds(context, contentUri, keys)
val maxSortIds = DataStoreUtils.getOldestStatusSortIds(context, contentUri, keys)
return@lazy Array(keys.size) { idx ->
SinceMaxPagination.maxId(maxIds[idx], maxSortIds[idx])
}
}
override val hasMaxIds: Boolean
get() = true
override val shouldAbort: Boolean
get() = context == null
})
}
override fun triggerRefresh(): Boolean {
super.triggerRefresh()
getStatuses(object : SimpleRefreshTaskParam() {
getStatuses(object : RefreshTaskParam {
override val accountKeys: Array<UserKey> by lazy {
this@CursorStatusesFragment.accountKeys
}
override val hasMaxIds: Boolean
get() = false
override val sinceIds: Array<String?>?
get() = getNewestStatusIds(accountKeys)
override val sinceSortIds: LongArray?
get() = DataStoreUtils.getNewestStatusSortIds(context, contentUri, accountKeys.toNulls())
override val pagination by lazy {
val keys = accountKeys.toNulls()
val sinceIds = DataStoreUtils.getNewestStatusIds(context, contentUri, keys)
val sinceSortIds = DataStoreUtils.getNewestStatusSortIds(context, contentUri, keys)
return@lazy Array(keys.size) { idx ->
SinceMaxPagination.sinceId(sinceIds[idx], sinceSortIds[idx])
}
}
override val shouldAbort: Boolean
get() = context == null
@ -231,11 +226,6 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
return buildStatusFilterWhereClause(preferences, table, null)
}
protected fun getNewestStatusIds(accountKeys: Array<UserKey>): Array<String?>? {
val context = context ?: return null
return DataStoreUtils.getNewestStatusIds(context, contentUri, accountKeys.toNulls())
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
val context = context
@ -246,12 +236,6 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
}
}
protected fun getOldestStatusIds(accountKeys: Array<UserKey>): Array<String?>? {
val context = context ?: return null
return DataStoreUtils.getOldestStatusIds(context, contentUri, accountKeys.toNulls())
}
protected open fun processWhere(where: Expression, whereArgs: Array<String>): ParameterizedExpression {
return ParameterizedExpression(where, whereArgs)
}

View File

@ -23,6 +23,7 @@ import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.TwidereConstants.NOTIFICATION_ID_HOME_TIMELINE
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_EXTRAS
import org.mariotaku.twidere.extension.model.hasMaxIds
import org.mariotaku.twidere.model.ParameterizedExpression
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey
@ -95,3 +96,4 @@ class HomeTimelineFragment : CursorStatusesFragment() {
}
}

View File

@ -31,6 +31,7 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.adapter.ListParcelableStatusesAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.extension.getErrorMessage
import org.mariotaku.twidere.extension.model.getMaxId
import org.mariotaku.twidere.loader.statuses.AbsRequestStatusesLoader
import org.mariotaku.twidere.model.BaseRefreshTaskParam
import org.mariotaku.twidere.model.ParcelableStatus
@ -67,13 +68,12 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
get() = Utils.getAccountKeys(context, arguments) ?: emptyArray()
private var lastId: String? = null
private var page = 1
private var pageDelta: Int = 0
private var nextPagination: Pagination? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
page = savedInstanceState.getInt(EXTRA_PAGE)
nextPagination = savedInstanceState.getParcelable(EXTRA_NEXT_PAGINATION)
}
}
@ -89,28 +89,27 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt(EXTRA_PAGE, page)
outState.putParcelable(EXTRA_NEXT_PAGINATION, nextPagination)
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableStatus>?> {
val loader = super.onCreateLoader(id, args)
if (loader is AbsRequestStatusesLoader) {
loader.pagination = args.getParcelable(EXTRA_PAGINATION)
}
return loader
}
override fun getStatuses(param: RefreshTaskParam): Boolean {
if (!loaderInitialized) return false
val args = Bundle(arguments)
val maxIds = param.maxIds
if (maxIds != null) {
args.putString(EXTRA_MAX_ID, maxIds[0])
val maxId = param.getMaxId(0)
if (maxId != null) {
args.putBoolean(EXTRA_MAKE_GAP, false)
}
val sinceIds = param.sinceIds
if (sinceIds != null) {
args.putString(EXTRA_SINCE_ID, sinceIds[0])
}
args.putBoolean(EXTRA_LOADING_MORE, param.isLoadingMore)
args.putBoolean(EXTRA_FROM_USER, true)
if (param is StatusesRefreshTaskParam) {
if (param.page > 0) {
args.putInt(EXTRA_PAGE, param.page)
}
}
args.putParcelable(EXTRA_PAGINATION, param.pagination?.getOrNull(0))
loaderManager.restartLoader(loaderId, args, this)
return true
}
@ -160,8 +159,8 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
if (statusCount <= 0) return
val status = adapter.getStatus(startIdx + statusCount - 1, true)
val accountKeys = arrayOf(status.account_key)
val maxIds = arrayOf<String?>(status.id)
val param = StatusesRefreshTaskParam(accountKeys, maxIds, null, page + pageDelta)
val pagination = arrayOf<Pagination?>(SinceMaxPagination.maxId(status.id, -1))
val param = BaseRefreshTaskParam(accountKeys, pagination)
param.isLoadingMore = true
getStatuses(param)
}
@ -172,20 +171,20 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
val statusStartIndex = adapter.statusStartIndex
if (statusStartIndex >= 0 && adapter.getStatusCount(true) > 0) {
val firstStatus = adapter.getStatus(statusStartIndex, true)
val sinceIds = Array(accountKeys.size) {
return@Array if (firstStatus.account_key == accountKeys[it]) firstStatus.id else null
}
getStatuses(BaseRefreshTaskParam(accountKeys, null, sinceIds))
val pagination = Array(accountKeys.size) {
if (firstStatus.account_key == accountKeys[it]) {
SinceMaxPagination.sinceId(firstStatus.id, -1)
} else {
getStatuses(BaseRefreshTaskParam(accountKeys, null, null))
null
}
}
getStatuses(BaseRefreshTaskParam(accountKeys, pagination))
} else {
getStatuses(BaseRefreshTaskParam(accountKeys, null))
}
return true
}
override fun onHasMoreDataChanged(hasMoreData: Boolean) {
pageDelta = if (hasMoreData) 1 else 0
}
fun removeStatus(statusId: String) {
val list = adapterData ?: return
val dataToRemove = HashSet<ParcelableStatus>()
@ -222,7 +221,6 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
adapter.notifyItemRangeChanged(rangeStart, rangeEnd)
}
private fun updateFavoritedStatus(status: ParcelableStatus) {
replaceStatusStates(status)
}
@ -281,21 +279,4 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
}
protected class StatusesRefreshTaskParam(
accountKeys: Array<UserKey>,
maxIds: Array<String?>?,
sinceIds: Array<String?>?,
var page: Int = -1
) : BaseRefreshTaskParam(accountKeys, maxIds, sinceIds)
companion object {
fun Bundle.toPagination(): Pagination {
val maxId = getString(EXTRA_MAX_ID)
val sinceId = getString(EXTRA_SINCE_ID)
return SinceMaxPagination().apply {
this.maxId = maxId
this.sinceId = sinceId
}
}
}
}

View File

@ -94,7 +94,6 @@ import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.view.calculateSpaceItemHeight
import org.mariotaku.twidere.fragment.AbsStatusesFragment.Companion.handleActionClick
import org.mariotaku.twidere.fragment.ParcelableStatusesFragment.Companion.toPagination
import org.mariotaku.twidere.loader.ParcelableStatusLoader
import org.mariotaku.twidere.loader.statuses.ConversationLoader
import org.mariotaku.twidere.menu.FavoriteItemProvider
@ -103,6 +102,8 @@ import org.mariotaku.twidere.model.analyzer.Share
import org.mariotaku.twidere.model.analyzer.StatusView
import org.mariotaku.twidere.model.event.FavoriteTaskEvent
import org.mariotaku.twidere.model.event.StatusListChangedEvent
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.*
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.task.AbsAccountRequestTask
@ -152,13 +153,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
adapter.isConversationsLoading = true
adapter.updateItemDecoration()
val status: ParcelableStatus = args.getParcelable(EXTRA_STATUS)
val maxId = args.getString(EXTRA_MAX_ID)
val sinceId = args.getString(EXTRA_SINCE_ID)
val maxSortId = args.getLong(EXTRA_MAX_SORT_ID)
val sinceSortId = args.getLong(EXTRA_SINCE_SORT_ID)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return ConversationLoader(activity, status, sinceSortId, maxSortId, adapter.getData(),
true, loadingMore).apply {
return ConversationLoader(activity, status, adapter.getData(), true, loadingMore).apply {
pagination = args.toPagination()
// Setting comparator to null lets statuses sort ascending
comparator = null
@ -171,7 +167,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
val conversationLoader = loader as ConversationLoader
var supportedPositions: Long = 0
if (data != null && !data.isEmpty()) {
if (conversationLoader.sinceSortId < data[data.size - 1].sort_id) {
val sinceSortId = (conversationLoader.pagination as? SinceMaxPagination)?.sinceSortId ?: -1
if (sinceSortId < data[data.size - 1].sort_id) {
supportedPositions = supportedPositions or ILoadMoreSupportAdapter.END
}
if (data[0].in_reply_to_status_id != null) {
@ -2181,5 +2178,18 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
private val STATE_LOADED = 1
private val STATE_LOADING = 2
private val STATE_ERROR = 3
fun Bundle.toPagination(): Pagination {
val maxId = getString(EXTRA_MAX_ID)
val sinceId = getString(EXTRA_SINCE_ID)
val maxSortId = getLong(EXTRA_MAX_SORT_ID)
val sinceSortId = getLong(EXTRA_SINCE_SORT_ID)
return SinceMaxPagination().apply {
this.maxId = maxId
this.sinceId = sinceId
this.maxSortId = maxSortId
this.sinceSortId = sinceSortId
}
}
}
}

View File

@ -109,9 +109,7 @@ class GroupTimelineFragment : ParcelableStatusesFragment() {
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return GroupTimelineLoader(activity, accountKey, groupId, groupName, adapterData,
savedStatusesFileArgs, tabPosition, fromUser, loadingMore).apply {
pagination = args.toPagination()
}
savedStatusesFileArgs, tabPosition, fromUser, loadingMore)
}
}

View File

@ -24,7 +24,6 @@ import android.os.Bundle
import android.support.v4.content.Loader
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.fragment.AbsMediaStatusesFragment
import org.mariotaku.twidere.fragment.ParcelableStatusesFragment.Companion.toPagination
import org.mariotaku.twidere.loader.statuses.MediaStatusesSearchLoader
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.util.Utils
@ -43,9 +42,7 @@ class MediaStatusesSearchFragment : AbsMediaStatusesFragment() {
val makeGap = args.getBoolean(EXTRA_MAKE_GAP, true)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return MediaStatusesSearchLoader(activity, accountKey, query, adapter.getData(), null, tabPosition,
fromUser, makeGap, loadingMore).apply {
pagination = args.toPagination()
}
fromUser, makeGap, loadingMore)
}
override fun getStatuses(maxId: String?, sinceId: String?): Int {

View File

@ -58,8 +58,6 @@ class NetworkPublicTimelineFragment : ParcelableStatusesFragment() {
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return NetworkPublicTimelineLoader(context, accountKey, data, savedStatusesFileArgs,
tabPosition, fromUser, loadingMore).apply {
pagination = args.toPagination()
}
tabPosition, fromUser, loadingMore)
}
}

View File

@ -58,8 +58,6 @@ class PublicTimelineFragment : ParcelableStatusesFragment() {
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return PublicTimelineLoader(context, accountKey, data, savedStatusesFileArgs, tabPosition,
fromUser, loadingMore).apply {
pagination = args.toPagination()
}
fromUser, loadingMore)
}
}

View File

@ -74,9 +74,7 @@ open class StatusesSearchFragment : ParcelableStatusesFragment() {
val makeGap = args.getBoolean(EXTRA_MAKE_GAP, true)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return TweetSearchLoader(activity, accountKey, query, adapterData, savedStatusesFileArgs, tabPosition, fromUser,
makeGap, loadingMore).apply {
pagination = args.toPagination()
}
makeGap, loadingMore)
}
override fun fitSystemWindows(insets: Rect) {

View File

@ -80,10 +80,8 @@ class UserFavoritesFragment : ParcelableStatusesFragment() {
val screenName = args.getString(EXTRA_SCREEN_NAME)
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return UserFavoritesLoader(context, accountKey, userKey, screenName, adapterData, savedStatusesFileArgs,
tabPosition, fromUser, loadingMore).apply {
pagination = args.toPagination()
}
return UserFavoritesLoader(context, accountKey, userKey, screenName, adapterData,
savedStatusesFileArgs, tabPosition, fromUser, loadingMore)
}
override fun notifyFavoriteTask(event: FavoriteTaskEvent) {

View File

@ -98,10 +98,8 @@ class UserListTimelineFragment : ParcelableStatusesFragment() {
val screenName = args.getString(EXTRA_SCREEN_NAME)
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return UserListTimelineLoader(activity, accountKey, listId, userKey, screenName,
listName, adapterData, savedStatusesFileArgs, tabPosition, fromUser, loadingMore).apply {
pagination = args.toPagination()
}
return UserListTimelineLoader(activity, accountKey, listId, userKey, screenName, listName,
adapterData, savedStatusesFileArgs, tabPosition, fromUser, loadingMore)
}
}

View File

@ -24,7 +24,6 @@ import android.os.Bundle
import android.support.v4.content.Loader
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.AbsMediaStatusesFragment
import org.mariotaku.twidere.fragment.ParcelableStatusesFragment.Companion.toPagination
import org.mariotaku.twidere.loader.statuses.MediaTimelineLoader
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
@ -41,10 +40,8 @@ class UserMediaTimelineFragment : AbsMediaStatusesFragment() {
val screenName = args.getString(EXTRA_SCREEN_NAME)
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return MediaTimelineLoader(context, accountKey, userKey, screenName, adapter.getData(), null,
tabPosition, fromUser, loadingMore).apply {
pagination = args.toPagination()
}
return MediaTimelineLoader(context, accountKey, userKey, screenName, adapter.getData(),
null, tabPosition, fromUser, loadingMore)
}

View File

@ -50,10 +50,8 @@ class UserMentionsFragment : StatusesSearchFragment() {
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val makeGap = args.getBoolean(EXTRA_MAKE_GAP, true)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return UserMentionsLoader(activity, accountKey, screenName, adapterData, savedStatusesFileArgs,
tabPosition, fromUser, makeGap, loadingMore).apply {
pagination = args.toPagination()
}
return UserMentionsLoader(activity, accountKey, screenName, adapterData,
savedStatusesFileArgs, tabPosition, fromUser, makeGap, loadingMore)
}
}

View File

@ -113,9 +113,7 @@ class UserTimelineFragment : ParcelableStatusesFragment() {
val pinnedIds = if (adapter.hasPinnedStatuses) null else pinnedStatusIds
return UserTimelineLoader(context, accountKey, userKey, screenName, profileUrl, data,
savedStatusesFileArgs, tabPosition, fromUser, loadingMore, pinnedIds,
timelineFilter as? UserTimelineFilter).apply {
pagination = args.toPagination()
}
timelineFilter as? UserTimelineFilter)
}
override fun onStatusesLoaded(loader: Loader<List<ParcelableStatus>?>, data: List<ParcelableStatus>?) {

View File

@ -43,8 +43,6 @@ import java.util.*
class ConversationLoader(
context: Context,
status: ParcelableStatus,
val sinceSortId: Long,
val maxSortId: Long,
adapterData: List<ParcelableStatus>?,
fromUser: Boolean,
loadingMore: Boolean
@ -100,6 +98,8 @@ class ConversationLoader(
val pagination = this.pagination as? SinceMaxPagination
val maxId = pagination?.maxId
val sinceId = pagination?.sinceId
val maxSortId = pagination?.maxSortId ?: -1
val sinceSortId = pagination?.sinceSortId ?: -1
val noSinceMaxId = maxId == null && sinceId == null
// Load conversations
if (maxId != null && maxSortId < status.sort_id || noSinceMaxId) {

View File

@ -1,16 +1,15 @@
package org.mariotaku.twidere.model
import org.mariotaku.twidere.model.pagination.Pagination
/**
* Created by mariotaku on 16/2/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
override val pagination: Array<out Pagination?>?
) : RefreshTaskParam {
override var extraId: Long = -1L
override var isLoadingMore: Boolean = false
override var shouldAbort: Boolean = false

View File

@ -1,34 +1,19 @@
package org.mariotaku.twidere.model
import org.mariotaku.twidere.model.pagination.Pagination
/**
* Created by mariotaku on 16/2/14.
*/
interface RefreshTaskParam {
val accountKeys: Array<UserKey>
val maxIds: Array<String?>?
val pagination: Array<out Pagination?>? get() = null
val sinceIds: Array<String?>?
val extraId: Long get() = -1
val cursors: Array<String?>?
val isLoadingMore: Boolean get() = false
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 extraId: Long
val isLoadingMore: Boolean
val shouldAbort: Boolean
val shouldAbort: Boolean get() = false
}

View File

@ -1,33 +1,17 @@
package org.mariotaku.twidere.model
import org.mariotaku.twidere.model.pagination.Pagination
/**
* Created by mariotaku on 16/2/14.
*/
abstract class SimpleRefreshTaskParam : RefreshTaskParam {
internal var cached: Array<UserKey>? = null
override val pagination: Array<out Pagination?>? = null
override val maxIds: Array<String?>?
get() = null
override val extraId: Long = -1
override val sinceIds: Array<String?>?
get() = null
override val isLoadingMore: Boolean = false
override val cursors: Array<String?>?
get() = null
override val sinceSortIds: LongArray?
get() = null
override val maxSortIds: LongArray?
get() = null
override val extraId: Long
get() = -1
override val isLoadingMore: Boolean
get() = false
override val shouldAbort: Boolean
get() = false
override val shouldAbort: Boolean = false
}

View File

@ -17,6 +17,7 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.toLongOr
import org.mariotaku.ktextension.toNulls
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.TwitterUserStream
@ -33,6 +34,7 @@ import org.mariotaku.twidere.constant.streamingPowerSavingKey
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
import org.mariotaku.twidere.model.util.UserKeyUtils
@ -420,18 +422,19 @@ class StreamingService : BaseService() {
@UiThread
private fun getInteractions() {
val task = GetActivitiesAboutMeTask(context)
task.params = object : SimpleRefreshTaskParam() {
task.params = object : RefreshTaskParam {
override val accountKeys: Array<UserKey> = arrayOf(account.key)
override val sinceIds: Array<String?>?
get() = DataStoreUtils.getNewestActivityMaxPositions(context,
Activities.AboutMe.CONTENT_URI, arrayOf(account.key), null, null)
override val sinceSortIds: LongArray?
get() = DataStoreUtils.getNewestActivityMaxSortPositions(context,
Activities.AboutMe.CONTENT_URI, arrayOf(account.key), null, null)
override val hasSinceIds: Boolean = true
override val pagination by lazy {
val keys = accountKeys.toNulls()
val sinceIds = DataStoreUtils.getRefreshNewestActivityMaxPositions(context,
Activities.AboutMe.CONTENT_URI, keys)
val sinceSortIds = DataStoreUtils.getRefreshNewestActivityMaxSortPositions(context,
Activities.AboutMe.CONTENT_URI, keys)
return@lazy Array(keys.size) { idx ->
SinceMaxPagination.sinceId(sinceIds[idx], sinceSortIds[idx])
}
}
}
TaskStarter.execute(task)
@ -442,8 +445,6 @@ class StreamingService : BaseService() {
val task = GetMessagesTask(context)
task.params = object : GetMessagesTask.RefreshMessagesTaskParam(context) {
override val accountKeys: Array<UserKey> = arrayOf(account.key)
override val hasSinceIds: Boolean = true
}
TaskStarter.execute(task)
}

View File

@ -17,9 +17,13 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_NOTIFY_CHANGE
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.extension.model.getMaxId
import org.mariotaku.twidere.extension.model.getMaxSortId
import org.mariotaku.twidere.extension.model.getSinceId
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.TwitterListResponse
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetActivitiesTaskEvent
import org.mariotaku.twidere.model.util.AccountUtils
@ -27,7 +31,6 @@ import org.mariotaku.twidere.model.util.ParcelableActivityUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.task.BaseAbstractTask
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.model.TwitterListResponse
import org.mariotaku.twidere.util.content.ContentResolverUtils
import java.util.*
@ -47,9 +50,6 @@ abstract class GetActivitiesTask(
override fun doLongOperation(param: RefreshTaskParam): List<TwitterListResponse<Activity>> {
if (param.shouldAbort) return emptyList()
val accountKeys = param.accountKeys
val maxIds = param.maxIds
val maxSortIds = param.maxSortIds
val sinceIds = param.sinceIds
val cr = context.contentResolver
val result = ArrayList<TwitterListResponse<Activity>>()
val loadItemLimit = preferences[loadItemLimitKey]
@ -61,28 +61,19 @@ abstract class GetActivitiesTask(
val microBlog = credentials.newMicroBlogInstance(context = context, cls = MicroBlog::class.java)
val paging = Paging()
paging.count(loadItemLimit)
var maxId: String? = null
var maxSortId: Long = -1
if (maxIds != null) {
maxId = maxIds[i]
if (maxSortIds != null) {
maxSortId = maxSortIds[i]
}
val maxId = param.getMaxId(i)
val maxSortId = param.getMaxSortId(i)
if (maxId != null) {
paging.maxId(maxId)
}
}
var sinceId: String? = null
if (sinceIds != null) {
sinceId = sinceIds[i]
val sinceId = param.getSinceId(i)
if (sinceId != null) {
paging.sinceId(sinceId)
if (maxIds == null || maxId == null) {
if (maxId == null) {
paging.setLatestResults(true)
saveReadPosition[i] = true
}
}
}
// We should delete old activities has intersection with new items
try {
val activities = getActivities(microBlog, credentials, paging)

View File

@ -19,8 +19,8 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_NOTIFY_CHANGE
import org.mariotaku.twidere.constant.loadItemLimitKey
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.event.GetStatusesTaskEvent
import org.mariotaku.twidere.model.util.AccountUtils
@ -52,10 +52,6 @@ abstract class GetStatusesTask(
override fun doLongOperation(param: RefreshTaskParam): List<StatusListResponse> {
if (param.shouldAbort) return emptyList()
val accountKeys = param.accountKeys
val maxIds = param.maxIds
val sinceIds = param.sinceIds
val maxSortIds = param.maxSortIds
val sinceSortIds = param.sinceSortIds
val result = ArrayList<StatusListResponse>()
val loadItemLimit = preferences[loadItemLimitKey]
var saveReadPosition = false
@ -67,22 +63,14 @@ abstract class GetStatusesTask(
try {
val paging = Paging()
paging.count(loadItemLimit)
val maxId: String?
val sinceId: String?
var maxSortId: Long = -1
var sinceSortId: Long = -1
if (maxIds != null && maxIds[i] != null) {
maxId = maxIds[i]
val maxId = param.getMaxId(i)
val sinceId = param.getSinceId(i)
val maxSortId = param.getMaxSortId(i)
val sinceSortId = param.getSinceSortId(i)
if (maxId != null) {
paging.maxId(maxId)
if (maxSortIds != null) {
maxSortId = maxSortIds[i]
}
} else {
maxSortId = -1
maxId = null
}
if (sinceIds != null && sinceIds[i] != null) {
sinceId = sinceIds[i]
if (sinceId != null) {
val sinceIdLong = sinceId.toLongOr(-1L)
//TODO handle non-twitter case
if (sinceIdLong != -1L) {
@ -90,15 +78,11 @@ abstract class GetStatusesTask(
} else {
paging.sinceId(sinceId)
}
if (sinceSortIds != null) {
sinceSortId = sinceSortIds[i]
}
if (maxIds == null) {
if (maxId == null) {
paging.setLatestResults(true)
}
saveReadPosition = true
} else {
sinceId = null
}
val statuses = getStatuses(microBlog, paging)
val storeResult = storeStatus(accountKey, details, statuses, sinceId, maxId,

View File

@ -39,16 +39,17 @@ import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_SHOW_NOTIFICATION
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
import org.mariotaku.twidere.model.message.conversation.DefaultConversationExtras
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
import org.mariotaku.twidere.model.pagination.CursorPagination
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
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.provider.TwidereDataStore.Messages
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
import org.mariotaku.twidere.task.BaseAbstractTask
@ -130,9 +131,10 @@ class GetMessagesTask(
private fun getDefaultMessages(microBlog: MicroBlog, details: AccountDetails,
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
val accountKey = details.key
val accountsCount = param.accountKeys.size
val sinceIds = if (param.hasSinceIds) param.sinceIds else null
val maxIds = if (param.hasMaxIds) param.maxIds else null
val receivedPagination = param.pagination?.get(index) as? SinceMaxPagination
val sincePagination = param.pagination?.get(accountsCount + index) as? SinceMaxPagination
val firstFetch by lazy {
val firstFetchPref = preferences.getBoolean(KEY_FIRST_FETCH, true)
@ -142,12 +144,14 @@ class GetMessagesTask(
return@lazy noConversationsBefore && firstFetchPref
}
val updateLastRead = maxIds != null || firstFetch
val updateLastRead = param.pagination?.all {
(it as? SinceMaxPagination)?.maxId != null
} ?: false || firstFetch
val received = microBlog.getDirectMessages(Paging().apply {
count(100)
val maxId = maxIds?.get(index)
val sinceId = sinceIds?.get(index)
val maxId = receivedPagination?.maxId
val sinceId = receivedPagination?.sinceId
if (maxId != null) {
maxId(maxId)
}
@ -157,9 +161,8 @@ class GetMessagesTask(
})
val sent = microBlog.getSentDirectMessages(Paging().apply {
count(100)
val accountsCount = param.accountKeys.size
val maxId = maxIds?.get(accountsCount + index)
val sinceId = sinceIds?.get(accountsCount + index)
val maxId = sincePagination?.maxId
val sinceId = sincePagination?.sinceId
if (maxId != null) {
maxId(maxId)
}
@ -201,7 +204,8 @@ class GetMessagesTask(
private fun getTwitterOfficialConversation(microBlog: MicroBlog, details: AccountDetails,
conversationId: String, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
val maxId = param.maxIds?.get(index) ?: return DatabaseUpdateData(emptyList(), emptyList())
val maxId = (param.pagination?.get(index) as? SinceMaxPagination)?.maxId
?: return DatabaseUpdateData(emptyList(), emptyList())
val paging = Paging().apply {
maxId(maxId)
}
@ -212,8 +216,8 @@ class GetMessagesTask(
private fun getTwitterOfficialUserInbox(microBlog: MicroBlog, details: AccountDetails,
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
val maxId = if (param.hasMaxIds) param.maxIds?.get(index) else null
val cursor = if (param.hasCursors) param.cursors?.get(index) else null
val maxId = (param.pagination?.get(index) as? SinceMaxPagination)?.maxId
val cursor = (param.pagination?.get(index) as? CursorPagination)?.cursor
val response = if (cursor != null) {
microBlog.getUserUpdates(cursor).userEvents
} else {
@ -231,7 +235,7 @@ class GetMessagesTask(
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
val accountKey = details.key
val accountType = details.type
val cursor = param.cursors?.get(index)
val cursor = (param.pagination?.get(index) as? CursorPagination)?.cursor
val page = cursor?.substringAfter("page:").toIntOr(-1)
val result = microBlog.getConversationList(Paging().apply {
count(60)
@ -272,36 +276,33 @@ class GetMessagesTask(
override val showNotification: Boolean = true
override val sinceIds: Array<String?>?
get() {
override val pagination by lazy {
val result = arrayOfNulls<Pagination>(accounts.size * 2)
val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
defaultKeys, false)
val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
defaultKeys, true)
return incomingIds + outgoingIds
val cursors = DataStoreUtils.getNewestConversations(context, Conversations.CONTENT_URI,
twitterOfficialKeys).mapToArray { it?.request_cursor }
accounts.forEachIndexed { index, details ->
if (details == null) return@forEachIndexed
if (details.isOfficial(context)) {
result[index] = CursorPagination.valueOf(cursors[index])
} else {
result[index] = SinceMaxPagination.sinceId(incomingIds[index], -1)
result[accounts.size + index] = SinceMaxPagination.sinceId(outgoingIds[index], -1)
}
}
return@lazy result
}
override val cursors: Array<String?>?
get() {
val cursors = arrayOfNulls<String>(defaultKeys.size)
val newestConversations = DataStoreUtils.getNewestConversations(context,
Conversations.CONTENT_URI, twitterOfficialKeys)
newestConversations.forEachIndexed { i, conversation ->
cursors[i] = conversation?.request_cursor
}
return cursors
}
override val hasSinceIds: Boolean = true
override val hasMaxIds: Boolean = false
override val hasCursors: Boolean = true
}
abstract class LoadMoreEntriesTaskParam(
context: Context
) : RefreshMessagesTaskParam(context) {
override val maxIds: Array<String?>? by lazy {
override val pagination: Array<out Pagination?>? by lazy {
val incomingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
defaultKeys, false)
val outgoingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
@ -312,11 +313,10 @@ class GetMessagesTask(
val extras = conversation?.conversation_extras as? TwitterOfficialConversationExtras ?: return@forEachIndexed
incomingIds[i] = extras.maxEntryId
}
return@lazy incomingIds + outgoingIds
return@lazy (incomingIds + outgoingIds).mapToArray { maxId ->
SinceMaxPagination.maxId(maxId, -1)
}
}
override val hasSinceIds: Boolean = false
override val hasMaxIds: Boolean = true
}
class LoadMoreMessageTaskParam(
@ -325,14 +325,13 @@ class GetMessagesTask(
override val conversationId: String,
maxId: String
) : RefreshMessagesTaskParam(context) {
override val accountKeys: Array<UserKey> = arrayOf(accountKey)
override val maxIds: Array<String?>? = arrayOf(maxId)
override val hasMaxIds: Boolean = true
override val accountKeys = arrayOf(accountKey)
override val pagination = arrayOf(SinceMaxPagination.maxId(maxId, -1))
}
abstract class RefreshMessagesTaskParam(
val context: Context
) : SimpleRefreshTaskParam() {
) : RefreshTaskParam {
/**
* If `conversationId` has value, load messages in conversationId

View File

@ -46,6 +46,7 @@ import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.event.*
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableRelationshipUtils
import org.mariotaku.twidere.provider.TwidereDataStore.*
@ -272,28 +273,33 @@ class AsyncTwitterWrapper(
}
fun refreshAll(action: () -> Array<UserKey>): Boolean {
getHomeTimelineAsync(object : SimpleRefreshTaskParam() {
getHomeTimelineAsync(object : RefreshTaskParam {
override val accountKeys: Array<UserKey> by lazy { action() }
override val accountKeys by lazy { action() }
override val sinceIds: Array<String?>? by lazy {
DataStoreUtils.getNewestStatusIds(context, Statuses.CONTENT_URI,
accountKeys.toNulls())
override val pagination by lazy {
return@lazy DataStoreUtils.getNewestStatusIds(context, Statuses.CONTENT_URI,
accountKeys.toNulls()).mapToArray {
return@mapToArray SinceMaxPagination.sinceId(it, -1)
}
}
})
if (preferences[homeRefreshMentionsKey]) {
getActivitiesAboutMeAsync(object : SimpleRefreshTaskParam() {
override val accountKeys: Array<UserKey> by lazy { action() }
getActivitiesAboutMeAsync(object : RefreshTaskParam {
override val sinceIds: Array<String?>? by lazy {
DataStoreUtils.getRefreshNewestActivityMaxPositions(context,
Activities.AboutMe.CONTENT_URI, accountKeys.toNulls())
override val accountKeys by lazy { action() }
override val pagination by lazy {
return@lazy DataStoreUtils.getRefreshNewestActivityMaxPositions(context,
Activities.AboutMe.CONTENT_URI, accountKeys.toNulls()).mapToArray {
return@mapToArray SinceMaxPagination.sinceId(it, -1)
}
}
})
}
if (preferences[homeRefreshDirectMessagesKey]) {
getMessagesAsync(object : GetMessagesTask.RefreshMessagesTaskParam(context) {
override val accountKeys: Array<UserKey> by lazy { action() }
override val accountKeys by lazy { action() }
})
}
if (preferences[homeRefreshSavedSearchesKey]) {

View File

@ -15,8 +15,10 @@ import org.mariotaku.twidere.constant.IntentConstants.INTENT_PACKAGE_PREFIX
import org.mariotaku.twidere.constant.dataSyncProviderInfoKey
import org.mariotaku.twidere.constant.stopAutoRefreshWhenBatteryLowKey
import org.mariotaku.twidere.model.AccountPreferences
import org.mariotaku.twidere.model.SimpleRefreshTaskParam
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.pagination.Pagination
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask
@ -105,7 +107,8 @@ class TaskServiceRunner(
val preferences: SharedPreferences,
val refreshable: (AccountPreferences) -> Boolean,
val getSinceIds: (Array<UserKey>) -> Array<String?>?
) : SimpleRefreshTaskParam() {
) : RefreshTaskParam {
override val accountKeys: Array<UserKey> by lazy {
return@lazy AccountPreferences.getAccountPreferences(context, preferences,
DataStoreUtils.getAccountKeys(context)).filter {
@ -113,8 +116,10 @@ class TaskServiceRunner(
}.mapToArray(AccountPreferences::accountKey)
}
override val sinceIds: Array<String?>?
get() = getSinceIds(accountKeys)
override val pagination: Array<Pagination?>?
get() = getSinceIds(accountKeys)?.mapToArray { sinceId ->
SinceMaxPagination().also { it.sinceId = sinceId }
}
}