implemented mastodon interactions timeline

This commit is contained in:
Mariotaku Lee 2017-04-22 01:38:47 +08:00
parent dad16bdc3b
commit d1b175b524
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
12 changed files with 251 additions and 108 deletions

View File

@ -18,9 +18,18 @@
package org.mariotaku.microblog.library.mastodon.api;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.mastodon.model.LinkHeaderList;
import org.mariotaku.microblog.library.mastodon.model.Notification;
import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Query;
/**
* Created by mariotaku on 2017/4/17.
*/
public interface NotificationsResources {
@GET("/v1/notifications")
LinkHeaderList<Notification> getNotifications(@Query Paging paging) throws MicroBlogException;
}

View File

@ -18,6 +18,8 @@
package org.mariotaku.microblog.library.mastodon.model;
import android.support.annotation.StringDef;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
@ -36,7 +38,8 @@ public class Notification {
@JsonField(name = "id")
String id;
/**
* One of: {@code mention}, {@code reblog}, {@code favourite}, {@code follow}
* One of: {@link Type#MENTION}, {@link Type#REBLOG}, {@link Type#FAVOURITE},
* {@link Type#FOLLOW}
*/
@JsonField(name = "type")
String type;
@ -86,4 +89,9 @@ public class Notification {
", status=" + status +
'}';
}
@StringDef({Type.MENTION, Type.REBLOG, Type.FAVOURITE, Type.FOLLOW})
public @interface Type {
String MENTION = "mention", REBLOG = "reblog", FAVOURITE = "favourite", FOLLOW = "follow";
}
}

View File

@ -97,7 +97,7 @@ public class ParcelableActivity implements Comparable<ParcelableActivity>, Parce
@ParcelableThisPlease
@JsonField(name = "source_ids", typeConverter = UserKeysConverter.class)
@CursorField(value = Activities.SOURCE_IDS, converter = UserKeysCursorFieldConverter.class)
public UserKey[] source_ids;
public UserKey[] source_keys;
@ParcelableThisPlease
@JsonField(name = "sources")
@ -215,7 +215,7 @@ public class ParcelableActivity implements Comparable<ParcelableActivity>, Parce
", max_position='" + max_position + '\'' +
", min_position='" + min_position + '\'' +
", action='" + action + '\'' +
", source_ids=" + Arrays.toString(source_ids) +
", source_ids=" + Arrays.toString(source_keys) +
", sources=" + Arrays.toString(sources) +
", target_users=" + Arrays.toString(target_users) +
", target_statuses=" + Arrays.toString(target_statuses) +

View File

@ -34,12 +34,12 @@ import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.microblog.library.twitter.model.DirectMessage
import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ActivityTitleSummaryMessage
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
import org.mariotaku.twidere.util.UserColorNameManager
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.streaming.FanfouTimelineStreamCallback
@ -118,8 +118,7 @@ class UserStreamDumperPlugin(val context: Context) : DumperPlugin {
if (verboseMode) {
dumpContext.stdout.println("Activity: @${activity.toString().trim('\n')}")
} else {
val pActivity = ParcelableActivityUtils.fromActivity(activity, account.key,
account.type)
val pActivity = activity.toParcelable(account.key, account.type)
val message = ActivityTitleSummaryMessage.get(context, manager, pActivity,
pActivity.sources, 0, true, true)
if (message != null) {
@ -173,8 +172,7 @@ class UserStreamDumperPlugin(val context: Context) : DumperPlugin {
override fun onActivityAboutMe(activity: Activity): Boolean {
if (!includeInteractions && includeTimeline) return true
val pActivity = ParcelableActivityUtils.fromActivity(activity, account.key,
account.type)
val pActivity = activity.toParcelable(account.key, account.type)
val message = ActivityTitleSummaryMessage.get(context, manager, pActivity, pActivity.sources, 0,
true, true)
if (message != null) {

View File

@ -0,0 +1,74 @@
/*
* 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.api.mastodon
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.microblog.library.mastodon.model.Notification
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
/**
* Created by mariotaku on 2017/4/22.
*/
fun Notification.toParcelable(accountKey: UserKey): ParcelableActivity {
val result = ParcelableActivity()
result.account_key = accountKey
result.timestamp = createdAt.time
result.min_position = id
result.max_position = id
result.min_sort_position = result.timestamp
result.max_sort_position = result.timestamp
result.sources = toSources(accountKey)
when (type) {
Notification.Type.MENTION -> {
result.action = Activity.Action.MENTION
result.target_object_statuses = toStatuses(accountKey)
}
Notification.Type.REBLOG -> {
result.action = Activity.Action.RETWEET
result.target_object_statuses = toStatuses(accountKey)
}
Notification.Type.FAVOURITE -> {
result.action = Activity.Action.FAVORITE
result.target_statuses = toStatuses(accountKey)
}
Notification.Type.FOLLOW -> {
result.action = Activity.Action.FOLLOW
}
else -> {
result.action = type
}
}
result.source_keys = result.sources?.mapToArray { it.key }
return result
}
private fun Notification.toSources(accountKey: UserKey): Array<ParcelableUser>? {
val account = this.account ?: return null
return arrayOf(account.toParcelable(accountKey))
}
private fun Notification.toStatuses(accountKey: UserKey): Array<ParcelableStatus>? {
val status = this.status ?: return null
return arrayOf(status.toParcelable(accountKey))
}

View File

@ -0,0 +1,65 @@
/*
* 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.api.microblog
import org.mariotaku.ktextension.mapToArray
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.twidere.extension.model.toParcelables
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.UserKey
/**
* Created by mariotaku on 2017/4/22.
*/
fun Activity.toParcelable(accountKey: UserKey, accountType: String, isGap: Boolean = false,
profileImageSize: String = "normal"): ParcelableActivity {
val result = ParcelableActivity()
result.account_key = accountKey
result.timestamp = createdAt.time
result.action = action
result.max_sort_position = maxSortPosition
result.min_sort_position = minSortPosition
result.max_position = maxPosition
result.min_position = minPosition
result.sources = sources?.toParcelables(accountKey, accountType,
profileImageSize)
result.target_users = targetUsers?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_user_lists = targetUserLists?.toParcelables(accountKey,
profileImageSize)
result.target_statuses = targetStatuses?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_object_statuses = targetObjectStatuses?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_object_user_lists = targetObjectUserLists?.toParcelables(accountKey,
profileImageSize)
result.target_object_users = targetObjectUsers?.toParcelables(accountKey, accountType,
profileImageSize)
result.has_following_source = sources?.fold(false) { folded, item ->
if (item.isFollowing == true) {
return@fold true
}
return@fold folded
} ?: false
result.source_keys = result.sources?.mapToArray { it.key }
result.is_gap = isGap
return result
}

View File

@ -0,0 +1,22 @@
/*
* 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.model.task
data class GetTimelineResult(val exception: Exception?)

View File

@ -1,7 +1,5 @@
package org.mariotaku.twidere.model.util
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.twidere.extension.model.toParcelables
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
@ -41,7 +39,7 @@ object ParcelableActivityUtils {
activity.after_filtered_source_ids = list.toTypedArray()
return true
} else {
activity.after_filtered_source_ids = activity.source_ids
activity.after_filtered_source_ids = activity.source_keys
return false
}
}
@ -58,45 +56,5 @@ object ParcelableActivityUtils {
return result
}
fun fromActivity(activity: Activity, accountKey: UserKey, accountType: String,
isGap: Boolean = false, profileImageSize: String = "normal"): ParcelableActivity {
val result = ParcelableActivity()
result.account_key = accountKey
result.timestamp = activity.createdAt.time
result.action = activity.action
result.max_sort_position = activity.maxSortPosition
result.min_sort_position = activity.minSortPosition
result.max_position = activity.maxPosition
result.min_position = activity.minPosition
result.sources = activity.sources?.toParcelables(accountKey, accountType,
profileImageSize)
result.target_users = activity.targetUsers?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_user_lists = activity.targetUserLists?.toParcelables(accountKey,
profileImageSize)
result.target_statuses = activity.targetStatuses?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_object_statuses = activity.targetObjectStatuses?.toParcelables(accountKey,
accountType, profileImageSize)
result.target_object_user_lists = activity.targetObjectUserLists?.toParcelables(accountKey,
profileImageSize)
result.target_object_users = activity.targetObjectUsers?.toParcelables(accountKey, accountType,
profileImageSize)
result.has_following_source = activity.sources?.fold(false) { folded, item ->
if (item.isFollowing == true) {
return@fold true
}
return@fold folded
} ?: false
if (result.sources != null) {
result.source_ids = arrayOfNulls<UserKey>(result.sources.size)
for (i in result.sources.indices) {
result.source_ids[i] = result.sources[i].key
}
}
result.is_gap = isGap
return result
}
}

View File

@ -32,6 +32,7 @@ import org.mariotaku.twidere.constant.streamingEnabledKey
import org.mariotaku.twidere.constant.streamingNonMeteredNetworkKey
import org.mariotaku.twidere.constant.streamingPowerSavingKey
import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.pagination.SinceMaxPagination
@ -315,8 +316,8 @@ class StreamingService : BaseService() {
} else {
insertGap = false
}
val curActivity = ParcelableActivityUtils.fromActivity(activity, account.key,
account.type, insertGap, profileImageSize)
val curActivity = activity.toParcelable(account.key, account.type, insertGap,
profileImageSize)
curActivity.account_color = account.color
curActivity.position_key = curActivity.timestamp
var updateId = -1L

View File

@ -23,12 +23,18 @@ import android.content.Context
import android.net.Uri
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.mastodon.Mastodon
import org.mariotaku.microblog.library.twitter.model.*
import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.fragment.InteractionsTimelineFragment
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableActivity
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
import org.mariotaku.twidere.util.ErrorInfoStore
@ -45,24 +51,38 @@ class GetActivitiesAboutMeTask(context: Context) : GetActivitiesTask(context) {
override val contentUri: Uri
get() = Activities.AboutMe.CONTENT_URI
private val profileImageSize = context.getString(R.string.profile_image_size)
@Throws(MicroBlogException::class)
override fun getActivities(twitter: MicroBlog, details: AccountDetails, paging: Paging):
ResponseList<Activity> {
if (details.isOfficial(context)) {
return twitter.getActivitiesAboutMe(paging)
}
val activities = ResponseList<Activity>()
val statuses: ResponseList<Status>
when (details.type) {
override fun getActivities(account: AccountDetails, paging: Paging): List<ParcelableActivity> {
when (account.type) {
AccountType.MASTODON -> {
val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java)
return mastodon.getNotifications(paging).map {
it.toParcelable(account.key)
}
}
AccountType.FANFOU -> {
statuses = twitter.getMentions(paging)
val microBlog = account.newMicroBlogInstance(context, MicroBlog::class.java)
if (account.isOfficial(context)) {
return microBlog.getActivitiesAboutMe(paging).map {
it.toParcelable(account.key, account.type, profileImageSize = profileImageSize)
}
}
return microBlog.getMentions(paging).map {
InternalActivityCreator.status(it, account.key.id).toParcelable(account.key,
account.type, profileImageSize = profileImageSize)
}
}
else -> {
statuses = twitter.getMentionsTimeline(paging)
val microBlog = account.newMicroBlogInstance(context, MicroBlog::class.java)
return microBlog.getHomeTimeline(paging).map {
InternalActivityCreator.status(it, account.key.id).toParcelable(account.key,
account.type, profileImageSize = profileImageSize)
}
}
}
statuses.mapTo(activities) { InternalActivityCreator.status(it, details.key.id) }
return activities
}

View File

@ -1,17 +1,13 @@
package org.mariotaku.twidere.task.twitter
import android.accounts.AccountManager
import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.support.annotation.UiThread
import org.mariotaku.kpreferences.get
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.microblog.library.twitter.model.Paging
import org.mariotaku.microblog.library.twitter.model.ResponseList
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
@ -20,14 +16,13 @@ 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.ParcelableActivity
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.task.GetTimelineResult
import org.mariotaku.twidere.model.util.AccountUtils
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.*
@ -39,26 +34,21 @@ import java.util.*
*/
abstract class GetActivitiesTask(
context: Context
) : BaseAbstractTask<RefreshTaskParam, List<TwitterListResponse<Activity>>, (Boolean) -> Unit>(context) {
private val profileImageSize = context.getString(R.string.profile_image_size)
) : BaseAbstractTask<RefreshTaskParam, List<GetTimelineResult?>, (Boolean) -> Unit>(context) {
protected abstract val errorInfoKey: String
protected abstract val contentUri: Uri
override fun doLongOperation(param: RefreshTaskParam): List<TwitterListResponse<Activity>> {
override fun doLongOperation(param: RefreshTaskParam): List<GetTimelineResult?> {
if (param.shouldAbort) return emptyList()
val accountKeys = param.accountKeys
val cr = context.contentResolver
val result = ArrayList<TwitterListResponse<Activity>>()
val loadItemLimit = preferences[loadItemLimitKey]
val saveReadPosition = BooleanArray(accountKeys.size)
accountKeys.forEachIndexed { i, accountKey ->
val result = accountKeys.mapIndexed { i, accountKey ->
val noItemsBefore = DataStoreUtils.getActivitiesCount(context, contentUri, accountKey) <= 0
val credentials = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey,
true) ?: return@forEachIndexed
val microBlog = credentials.newMicroBlogInstance(context = context, cls = MicroBlog::class.java)
true) ?: return@mapIndexed null
val paging = Paging()
paging.count(loadItemLimit)
val maxId = param.getMaxId(i)
@ -76,9 +66,9 @@ abstract class GetActivitiesTask(
}
// We should delete old activities has intersection with new items
try {
val activities = getActivities(microBlog, credentials, paging)
val storeResult = storeActivities(cr, loadItemLimit, credentials, noItemsBefore,
activities, sinceId, maxId, false)
val activities = getActivities(credentials, paging)
val storeResult = storeActivities(credentials, activities, sinceId, maxId,
loadItemLimit, noItemsBefore, false)
if (saveReadPosition[i]) {
}
@ -93,17 +83,19 @@ abstract class GetActivitiesTask(
} else if (e.isCausedByNetworkIssue) {
errorInfoStore[errorInfoKey, accountKey] = ErrorInfoStore.CODE_NETWORK_ERROR
}
return@mapIndexed GetTimelineResult(e)
} catch (e: GetStatusesTask.GetTimelineException) {
result.add(TwitterListResponse(accountKey, e))
return@mapIndexed GetTimelineResult(e)
}
return@mapIndexed GetTimelineResult(null)
}
setLocalReadPosition(accountKeys, saveReadPosition)
return result
}
override fun afterExecute(handler: ((Boolean) -> Unit)?, result: List<TwitterListResponse<Activity>>) {
override fun afterExecute(handler: ((Boolean) -> Unit)?, result: List<GetTimelineResult?>) {
context.contentResolver.notifyChange(contentUri, null)
val exception = AsyncTwitterWrapper.getException(result)
val exception = result.firstOrNull { it?.exception != null }?.exception
bus.post(GetActivitiesTaskEvent(contentUri, false, exception))
handler?.invoke(true)
}
@ -114,26 +106,24 @@ abstract class GetActivitiesTask(
}
@Throws(MicroBlogException::class)
protected abstract fun getActivities(twitter: MicroBlog, details: AccountDetails, paging: Paging): ResponseList<Activity>
protected abstract fun getActivities(account: AccountDetails, paging: Paging): List<ParcelableActivity>
protected abstract fun setLocalReadPosition(accountKeys: Array<UserKey>, saveReadPosition: BooleanArray)
private fun storeActivities(cr: ContentResolver, loadItemLimit: Int, details: AccountDetails,
noItemsBefore: Boolean, activities: ResponseList<Activity>,
sinceId: String?, maxId: String?, notify: Boolean): Int {
private fun storeActivities(details: AccountDetails, activities: List<ParcelableActivity>,
sinceId: String?, maxId: String?, loadItemLimit: Int, noItemsBefore: Boolean,
notify: Boolean): Int {
val cr = context.contentResolver
val deleteBound = LongArray(2) { -1 }
val valuesList = ArrayList<ContentValues>()
var minIdx = -1
var minPositionKey: Long = -1
if (!activities.isEmpty()) {
val firstSortId = activities.first().createdAt.time
val lastSortId = activities.last().createdAt.time
val firstSortId = activities.first().timestamp
val lastSortId = activities.last().timestamp
// Get id diff of first and last item
val sortDiff = firstSortId - lastSortId
for (i in activities.indices) {
val item = activities[i]
val activity = ParcelableActivityUtils.fromActivity(item, details.key, details.type,
false, profileImageSize)
activities.forEachIndexed { i, activity ->
mediaPreloader.preloadActivity(activity)
activity.position_key = GetStatusesTask.getPositionKey(activity.timestamp,
activity.timestamp, lastSortId, sortDiff, i, activities.size)
@ -147,7 +137,7 @@ abstract class GetActivitiesTask(
} else {
deleteBound[1] = Math.max(deleteBound[1], activity.max_sort_position)
}
if (minIdx == -1 || item < activities[minIdx]) {
if (minIdx == -1 || activity < activities[minIdx]) {
minIdx = i
minPositionKey = activity.position_key
}

View File

@ -25,6 +25,7 @@ import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.RefreshTaskParam
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.GetStatusesTaskEvent
import org.mariotaku.twidere.model.task.GetTimelineResult
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.provider.TwidereDataStore.AccountSupportColumns
@ -41,13 +42,13 @@ import org.mariotaku.twidere.util.content.ContentResolverUtils
*/
abstract class GetStatusesTask(
context: Context
) : BaseAbstractTask<RefreshTaskParam, List<GetStatusesTask.GetStatusesResult?>, (Boolean) -> Unit>(context) {
) : BaseAbstractTask<RefreshTaskParam, List<GetTimelineResult?>, (Boolean) -> Unit>(context) {
protected abstract val contentUri: Uri
protected abstract val errorInfoKey: String
override fun doLongOperation(param: RefreshTaskParam): List<GetStatusesResult?> {
override fun doLongOperation(param: RefreshTaskParam): List<GetTimelineResult?> {
if (param.shouldAbort) return emptyList()
val accountKeys = param.accountKeys
val loadItemLimit = preferences[loadItemLimitKey]
@ -90,7 +91,7 @@ abstract class GetStatusesTask(
if (storeResult != 0) {
throw GetTimelineException(storeResult)
}
return@mapIndexed GetStatusesResult(null)
return@mapIndexed GetTimelineResult(null)
} catch (e: MicroBlogException) {
DebugLog.w(LOGTAG, tr = e)
if (e.isCausedByNetworkIssue) {
@ -98,14 +99,14 @@ abstract class GetStatusesTask(
} else if (e.statusCode == 401) {
// Unauthorized
}
return@mapIndexed GetStatusesResult(e)
return@mapIndexed GetTimelineResult(e)
} catch (e: GetTimelineException) {
return@mapIndexed GetStatusesResult(e)
return@mapIndexed GetTimelineResult(e)
}
}
}
override fun afterExecute(handler: ((Boolean) -> Unit)?, result: List<GetStatusesResult?>) {
override fun afterExecute(handler: ((Boolean) -> Unit)?, result: List<GetTimelineResult?>) {
context.contentResolver.notifyChange(contentUri, null)
val exception = result.firstOrNull { it?.exception != null }?.exception
bus.post(GetStatusesTaskEvent(contentUri, false, exception))
@ -141,8 +142,7 @@ abstract class GetStatusesTask(
val sortDiff = firstSortId - lastSortId
val creator = ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java)
for (i in 0 until statuses.size) {
val status = statuses[i]
statuses.forEachIndexed { i, status ->
ParcelableStatusUtils.updateExtraInformation(status, account)
status.position_key = getPositionKey(status.timestamp, status.sort_id, lastSortId,
sortDiff, i, statuses.size)
@ -210,8 +210,6 @@ abstract class GetStatusesTask(
}
}
data class GetStatusesResult(val exception: Exception?)
companion object {
const val ERROR_LOAD_GAP = 1