From 8fc93f1d2e334dda6abb56a5cc4f7993354d6ea7 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Sat, 22 Apr 2017 00:32:03 +0800 Subject: [PATCH] migrated status pagination --- .../library/mastodon/model/Status.java | 17 ++++ .../twidere/constant/IntentConstants.java | 3 - .../model/pagination/CursorPagination.java | 12 +++ .../model/pagination/SinceMaxPagination.java | 37 ++++++++ .../activity/UserListSelectorActivity.kt | 5 +- .../model/RefreshTaskParamExtensions.kt | 44 ++++++++++ .../model/api/mastodon/StatusExtensions.kt | 1 + .../twidere/fragment/AbsActivitiesFragment.kt | 8 +- .../twidere/fragment/AbsStatusesFragment.kt | 7 +- .../fragment/CursorActivitiesFragment.kt | 57 +++++-------- .../fragment/CursorStatusesFragment.kt | 56 +++++------- .../twidere/fragment/HomeTimelineFragment.kt | 2 + .../fragment/ParcelableStatusesFragment.kt | 69 ++++++--------- .../twidere/fragment/StatusFragment.kt | 26 ++++-- .../statuses/GroupTimelineFragment.kt | 4 +- .../statuses/MediaStatusesSearchFragment.kt | 5 +- .../statuses/NetworkPublicTimelineFragment.kt | 4 +- .../statuses/PublicTimelineFragment.kt | 4 +- .../statuses/StatusesSearchFragment.kt | 4 +- .../statuses/UserFavoritesFragment.kt | 6 +- .../statuses/UserListTimelineFragment.kt | 6 +- .../statuses/UserMediaTimelineFragment.kt | 7 +- .../fragment/statuses/UserMentionsFragment.kt | 6 +- .../fragment/statuses/UserTimelineFragment.kt | 4 +- .../loader/statuses/ConversationLoader.kt | 4 +- .../twidere/model/BaseRefreshTaskParam.kt | 9 +- .../twidere/model/RefreshTaskParam.kt | 27 ++---- .../twidere/model/SimpleRefreshTaskParam.kt | 28 ++---- .../twidere/service/StreamingService.kt | 25 +++--- .../twidere/task/twitter/GetActivitiesTask.kt | 35 +++----- .../twidere/task/twitter/GetStatusesTask.kt | 34 ++------ .../task/twitter/message/GetMessagesTask.kt | 85 +++++++++---------- .../twidere/util/AsyncTwitterWrapper.kt | 28 +++--- .../twidere/util/TaskServiceRunner.kt | 13 ++- 34 files changed, 344 insertions(+), 338 deletions(-) create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/RefreshTaskParamExtensions.kt diff --git a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/mastodon/model/Status.java b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/mastodon/model/Status.java index 66bca8a02..b47d2bf85 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/mastodon/model/Status.java +++ b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/mastodon/model/Status.java @@ -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{" + diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index e96b6c331..ea1d3ec7f 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -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"; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/pagination/CursorPagination.java b/twidere/src/main/java/org/mariotaku/twidere/model/pagination/CursorPagination.java index 922e75dad..4fb712bed 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/pagination/CursorPagination.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/pagination/CursorPagination.java @@ -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; diff --git a/twidere/src/main/java/org/mariotaku/twidere/model/pagination/SinceMaxPagination.java b/twidere/src/main/java/org/mariotaku/twidere/model/pagination/SinceMaxPagination.java index 51a4d70c5..a6c7a8cc1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/model/pagination/SinceMaxPagination.java +++ b/twidere/src/main/java/org/mariotaku/twidere/model/pagination/SinceMaxPagination.java @@ -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 CREATOR = new Creator() { public SinceMaxPagination createFromParcel(Parcel source) { SinceMaxPagination target = new SinceMaxPagination(); diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserListSelectorActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserListSelectorActivity.kt index 08752df8f..fb2ea2ebe 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserListSelectorActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/UserListSelectorActivity.kt @@ -148,8 +148,9 @@ class UserListSelectorActivity : BaseActivity(), override fun onCreateLoader(id: Int, args: Bundle): Loader> { val accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY) val userKey = args.getParcelable(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>?) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/RefreshTaskParamExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/RefreshTaskParamExtensions.kt new file mode 100644 index 000000000..0c5cf8ed9 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/RefreshTaskParamExtensions.kt @@ -0,0 +1,44 @@ +/* + * 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.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 +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/StatusExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/StatusExtensions.kt index 7c6fd1780..e25532ae6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/StatusExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/StatusExtensions.kt @@ -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 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsActivitiesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsActivitiesFragment.kt index d33718f4a..a9e8b9852 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsActivitiesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsActivitiesFragment.kt @@ -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 }) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsStatusesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsStatusesFragment.kt index 9580e76e0..c2e60e2d0 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsStatusesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsStatusesFragment.kt @@ -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(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, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt index d5ef36686..9ad069ca4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt @@ -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,27 +146,21 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() { super.onLoadMoreContents(position) if (position == 0L) return val contentUri = this.contentUri - getActivities(object : SimpleRefreshTaskParam() { - override val accountKeys: Array by lazy { + getActivities(object : RefreshTaskParam { + override val accountKeys by lazy { this@CursorActivitiesFragment.accountKeys } - override val maxIds: Array? - 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,27 +171,21 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() { override fun triggerRefresh(): Boolean { super.triggerRefresh() val contentUri = this.contentUri - getActivities(object : SimpleRefreshTaskParam() { - override val accountKeys: Array by lazy { + getActivities(object : RefreshTaskParam { + override val accountKeys by lazy { this@CursorActivitiesFragment.accountKeys } - override val sinceIds: Array? - 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 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt index b7a0fbc98..76f941aca 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt @@ -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 by lazy { + getStatuses(object : RefreshTaskParam { + override val accountKeys by lazy { this@CursorStatusesFragment.accountKeys } - override val maxIds: Array? - 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 by lazy { this@CursorStatusesFragment.accountKeys } - override val hasMaxIds: Boolean - get() = false - - override val sinceIds: Array? - 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): Array? { - 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): Array? { - val context = context ?: return null - return DataStoreUtils.getOldestStatusIds(context, contentUri, accountKeys.toNulls()) - } - protected open fun processWhere(where: Expression, whereArgs: Array): ParameterizedExpression { return ParameterizedExpression(where, whereArgs) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/HomeTimelineFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/HomeTimelineFragment.kt index 5a60bc12c..fd605f70d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/HomeTimelineFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/HomeTimelineFragment.kt @@ -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() { } } + diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableStatusesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableStatusesFragment.kt index e4ccac705..d806667bd 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableStatusesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableStatusesFragment.kt @@ -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?> { + 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(status.id) - val param = StatusesRefreshTaskParam(accountKeys, maxIds, null, page + pageDelta) + val pagination = arrayOf(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 + val pagination = Array(accountKeys.size) { + if (firstStatus.account_key == accountKeys[it]) { + SinceMaxPagination.sinceId(firstStatus.id, -1) + } else { + null + } } - getStatuses(BaseRefreshTaskParam(accountKeys, null, sinceIds)) + getStatuses(BaseRefreshTaskParam(accountKeys, pagination)) } else { - getStatuses(BaseRefreshTaskParam(accountKeys, null, null)) + 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() @@ -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, - maxIds: Array?, - sinceIds: Array?, - 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 - } - } - } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt index 340adcc21..70ad20353 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt @@ -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?>, data: List?) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/statuses/ConversationLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/statuses/ConversationLoader.kt index c5ce606d0..6c5614988 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/statuses/ConversationLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/statuses/ConversationLoader.kt @@ -43,8 +43,6 @@ import java.util.* class ConversationLoader( context: Context, status: ParcelableStatus, - val sinceSortId: Long, - val maxSortId: Long, adapterData: List?, 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) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/BaseRefreshTaskParam.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/BaseRefreshTaskParam.kt index 63567785a..60eb878b3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/model/BaseRefreshTaskParam.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/BaseRefreshTaskParam.kt @@ -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, - override val maxIds: Array?, - override val sinceIds: Array?, - override val cursors: Array? = null, - override val maxSortIds: LongArray? = null, - override val sinceSortIds: LongArray? = null + override val pagination: Array? ) : RefreshTaskParam { + override var extraId: Long = -1L override var isLoadingMore: Boolean = false override var shouldAbort: Boolean = false diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/RefreshTaskParam.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/RefreshTaskParam.kt index 11b21b3f2..3dc7d7a64 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/model/RefreshTaskParam.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/RefreshTaskParam.kt @@ -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 - val maxIds: Array? + val pagination: Array? get() = null - val sinceIds: Array? + val extraId: Long get() = -1 - val cursors: Array? + 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 } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/SimpleRefreshTaskParam.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SimpleRefreshTaskParam.kt index fceaf1860..0eda8a358 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/model/SimpleRefreshTaskParam.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/SimpleRefreshTaskParam.kt @@ -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? = null + override val pagination: Array? = null - override val maxIds: Array? - get() = null + override val extraId: Long = -1 - override val sinceIds: Array? - get() = null + override val isLoadingMore: Boolean = false - override val cursors: Array? - 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 } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/StreamingService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/StreamingService.kt index c2635a0f8..87ada355f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/service/StreamingService.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/StreamingService.kt @@ -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 = arrayOf(account.key) - override val sinceIds: Array? - 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 = arrayOf(account.key) - - override val hasSinceIds: Boolean = true } TaskStarter.execute(task) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt index b0ca498a2..8f0ba9be0 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt @@ -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> { 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>() val loadItemLimit = preferences[loadItemLimitKey] @@ -61,26 +61,17 @@ 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] - } - if (maxId != null) { + 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] - if (sinceId != null) { - paging.sinceId(sinceId) - if (maxIds == null || maxId == null) { - paging.setLatestResults(true) - saveReadPosition[i] = true - } + val sinceId = param.getSinceId(i) + if (sinceId != null) { + paging.sinceId(sinceId) + if (maxId == null) { + paging.setLatestResults(true) + saveReadPosition[i] = true } } // We should delete old activities has intersection with new items diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt index b7fc6c820..9fb79247e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt @@ -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 { 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() 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, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt index 372c9feb3..95354f58d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt @@ -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? - get() { - val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI, - defaultKeys, false) - val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI, - defaultKeys, true) - return incomingIds + outgoingIds - } - - override val cursors: Array? - get() { - val cursors = arrayOfNulls(defaultKeys.size) - val newestConversations = DataStoreUtils.getNewestConversations(context, - Conversations.CONTENT_URI, twitterOfficialKeys) - newestConversations.forEachIndexed { i, conversation -> - cursors[i] = conversation?.request_cursor + override val pagination by lazy { + val result = arrayOfNulls(accounts.size * 2) + val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI, + defaultKeys, false) + val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI, + defaultKeys, true) + 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 cursors } + return@lazy result + } - 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? by lazy { + override val pagination: Array? 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 = arrayOf(accountKey) - override val maxIds: Array? = 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 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt index cfa10b6fd..deddc2133 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt @@ -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): Boolean { - getHomeTimelineAsync(object : SimpleRefreshTaskParam() { + getHomeTimelineAsync(object : RefreshTaskParam { - override val accountKeys: Array by lazy { action() } + override val accountKeys by lazy { action() } - override val sinceIds: Array? 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 by lazy { action() } + getActivitiesAboutMeAsync(object : RefreshTaskParam { - override val sinceIds: Array? 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 by lazy { action() } + override val accountKeys by lazy { action() } }) } if (preferences[homeRefreshSavedSearchesKey]) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/TaskServiceRunner.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/TaskServiceRunner.kt index 637d80261..01176aea4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/TaskServiceRunner.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/TaskServiceRunner.kt @@ -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) -> Array? - ) : SimpleRefreshTaskParam() { + ) : RefreshTaskParam { + override val accountKeys: Array 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? - get() = getSinceIds(accountKeys) + override val pagination: Array? + get() = getSinceIds(accountKeys)?.mapToArray { sinceId -> + SinceMaxPagination().also { it.sinceId = sinceId } + } }