diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java index 7733804fc..2d93e99db 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableActivity.java @@ -101,7 +101,7 @@ public class ParcelableActivity extends ParcelableStatus implements Parcelable { @JsonField(name = "has_following_source") public boolean has_following_source = true; - public transient UserKey[] after_filtered_source_keys; + public transient ParcelableLiteUser[] after_filtered_sources; public ParcelableActivity() { } diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableLiteUser.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableLiteUser.java index c804b0b2f..6fa5af840 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableLiteUser.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableLiteUser.java @@ -59,6 +59,10 @@ public class ParcelableLiteUser implements Parcelable { @CursorField(CachedUsers.PROFILE_IMAGE_URL) public String profile_image_url; + @JsonField(name = "is_following") + @CursorField(CachedUsers.IS_FOLLOWING) + public boolean is_following; + @Override public int describeContents() { return 0; diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ParcelableActivitiesAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ParcelableActivitiesAdapter.kt index 8146fbcaa..e9601bbd9 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ParcelableActivitiesAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ParcelableActivitiesAdapter.kt @@ -21,11 +21,9 @@ package org.mariotaku.twidere.adapter import android.annotation.SuppressLint import android.content.Context -import android.database.Cursor import android.database.CursorIndexOutOfBoundsException import android.support.v4.widget.Space import android.support.v7.widget.RecyclerView -import android.util.SparseArray import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -47,9 +45,11 @@ import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.constant.newDocumentApiKey import org.mariotaku.twidere.fragment.CursorActivitiesFragment import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.util.ParcelableActivityUtils import org.mariotaku.twidere.model.util.activityStatus import org.mariotaku.twidere.provider.TwidereDataStore.Activities import org.mariotaku.twidere.util.IntentUtils +import org.mariotaku.twidere.util.JsonSerializer import org.mariotaku.twidere.util.OnLinkClickHandler import org.mariotaku.twidere.util.TwidereLinkify import org.mariotaku.twidere.view.holder.* @@ -133,45 +133,27 @@ class ParcelableActivitiesAdapter( private var filteredUserKeys: Array? = null private val gapLoadingIds: MutableSet = HashSet() private val reuseActivity = ParcelableActivity() - private val filterIdCache = SparseArray?>() + private var infoCache: Array? = null init { eventListener = EventListener(this) statusAdapterDelegate.updateOptions() + setHasStableIds(true) } override fun isGapItem(position: Int): Boolean { - val dataPosition = position - activityStartIndex - val activityCount = getActivityCount(false) - if (dataPosition < 0 || dataPosition >= activityCount) return false - // Don't show gap if it's last item - if (dataPosition == activityCount - 1) { - return false - } - if (data is ObjectCursor) { - val cursor = (data as ObjectCursor).cursor - if (!cursor.moveToPosition(dataPosition)) return false - val indices = (data as ObjectCursor).indices - return cursor.getInt(indices[Activities.IS_GAP]) == 1 - } - return data!![dataPosition].is_gap + return getFieldValue(position, readInfoValueAction = { + it.gap + }, readStatusValueAction = { activity -> + activity.is_gap + }, defValue = false, raw = false) } override fun getItemId(position: Int): Long { val countIndex = itemCounts.getItemCountIndex(position) when (countIndex) { ITEM_INDEX_ACTIVITY -> { - return getFieldValue(position, readCursorValueAction = { cursor, indices -> - val accountKey = UserKey.valueOf(cursor.getString(indices[Activities.ACCOUNT_KEY])) - val timestamp = cursor.getLong(indices[Activities.TIMESTAMP]) - val maxPosition = cursor.getLong(indices[Activities.MAX_SORT_POSITION]) - val minPosition = cursor.getLong(indices[Activities.MIN_SORT_POSITION]) - ParcelableActivity.calculateHashCode(accountKey, timestamp, maxPosition, - minPosition) - }, readStatusValueAction = { activity -> - ParcelableActivity.calculateHashCode(activity.account_key, activity.timestamp, - activity.max_sort_position, activity.min_sort_position) - }, defValue = -1, raw = false).toLong() + return getRowId(position, false) } else -> { return (countIndex.toLong() shl 32) or getItemViewType(position).toLong() @@ -193,6 +175,7 @@ class ParcelableActivitiesAdapter( filteredUserKeys = data.filteredUserIds } this.data = data + infoCache = if (data != null) arrayOfNulls(data.size) else null gapLoadingIds.clear() updateItemCount() notifyDataSetChanged() @@ -241,8 +224,8 @@ class ParcelableActivitiesAdapter( } ITEM_VIEW_TYPE_TITLE_SUMMARY -> { val activity = getActivityInternal(position, raw = false, reuse = true) - activity.after_filtered_source_keys = getAfterFilteredSourceKeys(position, false, - activity.source_keys) + val sources = getAfterFilteredSources(position, false) + activity.after_filtered_sources = sources (holder as ActivityTitleSummaryViewHolder).displayActivity(activity) } ITEM_VIEW_TYPE_STUB -> { @@ -275,11 +258,9 @@ class ParcelableActivitiesAdapter( Activity.Action.MEDIA_TAGGED, Activity.Action.RETWEETED_MEDIA_TAGGED, Activity.Action.FAVORITED_MEDIA_TAGGED, Activity.Action.JOINED_TWITTER -> { if (mentionsOnly) return ITEM_VIEW_TYPE_EMPTY - filteredUserKeys?.let { - val afterFiltered = getAfterFilteredSourceKeys(position, false) - if (afterFiltered != null && afterFiltered.isEmpty()) { - return ITEM_VIEW_TYPE_EMPTY - } + val afterFiltered = getAfterFilteredSources(position, false) + if (afterFiltered != null && afterFiltered.isEmpty()) { + return ITEM_VIEW_TYPE_EMPTY } return ITEM_VIEW_TYPE_TITLE_SUMMARY } @@ -324,38 +305,29 @@ class ParcelableActivitiesAdapter( } fun getTimestamp(adapterPosition: Int, raw: Boolean = false): Long { - return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices -> - cursor.safeGetLong(indices[Activities.TIMESTAMP]) + return getFieldValue(adapterPosition, readInfoValueAction = { + it.timestamp }, readStatusValueAction = { activity -> activity.timestamp }, defValue = -1, raw = raw) } fun getAction(adapterPosition: Int, raw: Boolean = false): String? { - return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices -> - cursor.getString(indices[Activities.ACTION]) + return getFieldValue(adapterPosition, readInfoValueAction = { + it.action }, readStatusValueAction = { activity -> activity.action }, defValue = null, raw = raw) } fun getRowId(adapterPosition: Int, raw: Boolean = false): Long { - return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices -> - cursor.safeGetLong(indices[Activities._ID]) + return getFieldValue(adapterPosition, readInfoValueAction = { + it._id }, readStatusValueAction = { activity -> - activity._id + activity.hashCode().toLong() }, defValue = -1L, raw = raw) } - - fun getSourceKeys(adapterPosition: Int, raw: Boolean = false): Array? { - return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices -> - cursor.getString(indices[Activities.SOURCE_KEYS])?.let(UserKey::arrayOf) - }, readStatusValueAction = { activity -> - activity.source_keys - }, defValue = null, raw = raw) - } - fun getData(): List? { return data } @@ -375,41 +347,53 @@ class ParcelableActivitiesAdapter( val data = this.data!! if (reuse && data is ObjectCursor) { val activity = data.setInto(dataPosition, reuseActivity) -// activity.after_filtered_source_ids = filterIdCache[activity._id] -// activity.after_filtered_sources = null + activity.after_filtered_sources = null return activity } else { return data[dataPosition] } } - private fun getAfterFilteredSourceKeys(position: Int, raw: Boolean, - sourceKeys: Array? = getSourceKeys(position, raw)): Array? { - return filterIdCache[position] ?: run { - val allFiltered = filteredUserKeys - val keys = if (allFiltered != null) { - sourceKeys?.filterNot { it in allFiltered }?.toTypedArray() - } else { - sourceKeys - } - filterIdCache.put(position, keys) - return@run keys - } + private fun getAfterFilteredSources(position: Int, raw: Boolean): Array? { + return getFieldValue(position, readInfoValueAction = { + it.filteredSources + }, readStatusValueAction = lambda2@ { activity -> + if (activity.after_filtered_sources != null) return@lambda2 activity.after_filtered_sources + val sources = ParcelableActivityUtils.filterSources(activity.sources_lite, + filteredUserKeys, followingOnly) + activity.after_filtered_sources = sources + return@lambda2 sources + }, defValue = null, raw = raw) } private inline fun getFieldValue(position: Int, - readCursorValueAction: (cursor: Cursor, indices: ObjectCursor.CursorIndices) -> T, + readInfoValueAction: (ActivityInfo) -> T, readStatusValueAction: (status: ParcelableActivity) -> T, defValue: T, raw: Boolean = false): T { + val data = data if (data is ObjectCursor) { val dataPosition = position - activityStartIndex if (dataPosition < 0 || dataPosition >= getActivityCount(true)) { throw CursorIndexOutOfBoundsException("index: $position, valid range is $0..${getActivityCount(true)}") } - val cursor = (data as ObjectCursor).cursor + val cursor = data.cursor if (!cursor.safeMoveToPosition(dataPosition)) return defValue - val indices = (data as ObjectCursor).indices - return readCursorValueAction(cursor, indices) + val indices = data.indices + val info = infoCache?.get(dataPosition) ?: run { + val _id = cursor.safeGetLong(indices[Activities._ID]) + val timestamp = cursor.safeGetLong(indices[Activities.TIMESTAMP]) + val action = cursor.getString(indices[Activities.ACTION]) + val gap = cursor.getInt(indices[Activities.IS_GAP]) == 1 + val sources = cursor.getString(indices[Activities.SOURCES_LITE])?.let { + JsonSerializer.parseArray(it, ParcelableLiteUser::class.java) + } + val filteredSources = ParcelableActivityUtils.filterSources(sources, filteredUserKeys, + followingOnly) + val newInfo = ActivityInfo(_id, timestamp, gap, action, filteredSources) + infoCache?.set(dataPosition, newInfo) + return@run newInfo + } + return readInfoValueAction(info) } return readStatusValueAction(getActivityInternal(position, raw, false)) } @@ -514,6 +498,14 @@ class ParcelableActivitiesAdapter( } } + data class ActivityInfo( + val _id: Long, + val timestamp: Long, + val gap: Boolean, + val action: String, + val filteredSources: Array? + ) + companion object { const val ITEM_VIEW_TYPE_STUB = 0 const val ITEM_VIEW_TYPE_GAP = 1 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/api/MastodonExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/api/MastodonExtensions.kt new file mode 100644 index 000000000..22ea7c549 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/api/MastodonExtensions.kt @@ -0,0 +1,39 @@ +/* + * 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.api + +import org.mariotaku.ktextension.subArray +import org.mariotaku.microblog.library.mastodon.Mastodon +import org.mariotaku.microblog.library.mastodon.model.Relationship + + +fun Mastodon.batchGetRelationships(ids: Collection): Map { + val list = ids.toList() + val indices = ids.indices + val result = HashMap() + @Suppress("LoopToCallChain") + for (i in indices step 100) { + val batch = list.subArray(i until (i + 100).coerceAtMost(indices.last)) + getRelationships(batch).forEach { + result[it.id] = it + } + } + return result +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableUserExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableUserExtensions.kt index 98f4aed19..a687e3b9b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableUserExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableUserExtensions.kt @@ -42,6 +42,7 @@ fun ParcelableUser.toLite(): ParcelableLiteUser { result.screen_name = screen_name result.name = name result.profile_image_url = profile_image_url + result.is_following = is_following return result } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/AccountExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/AccountExtensions.kt index cdac10764..01496c6ea 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/AccountExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/AccountExtensions.kt @@ -20,6 +20,7 @@ package org.mariotaku.twidere.extension.model.api.mastodon import org.mariotaku.microblog.library.mastodon.model.Account +import org.mariotaku.microblog.library.mastodon.model.Relationship import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.extension.model.api.isHtml import org.mariotaku.twidere.extension.model.api.spanItems @@ -34,13 +35,15 @@ import org.mariotaku.twidere.util.emoji.EmojioneTranslator * Created by mariotaku on 2017/4/18. */ -fun Account.toParcelable(details: AccountDetails, position: Long = 0): ParcelableUser { - return toParcelable(details.key, position).apply { +fun Account.toParcelable(details: AccountDetails, position: Long = 0, + relationship: Relationship? = null): ParcelableUser { + return toParcelable(details.key, position, relationship).apply { account_color = details.color } } -fun Account.toParcelable(accountKey: UserKey, position: Long = 0): ParcelableUser { +fun Account.toParcelable(accountKey: UserKey, position: Long = 0, + relationship: Relationship? = null): ParcelableUser { val obj = ParcelableUser() obj.position = position obj.account_key = accountKey @@ -68,6 +71,17 @@ fun Account.toParcelable(accountKey: UserKey, position: Long = 0): ParcelableUse obj.listed_count = -1 obj.media_count = -1 obj.user_type = AccountType.MASTODON + + val extras = ParcelableUser.Extras() + + if (relationship != null && relationship.id == id) { + obj.is_following = relationship.isFollowing + obj.is_follow_request_sent = relationship.isRequested + extras.followed_by = relationship.isFollowedBy + extras.muting = relationship.isMuting + extras.blocking = relationship.isBlocking + } + return obj } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/NotificationExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/NotificationExtensions.kt index 08be47daf..413fa82ec 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/NotificationExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/api/mastodon/NotificationExtensions.kt @@ -21,6 +21,7 @@ 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.mastodon.model.Relationship import org.mariotaku.microblog.library.twitter.model.Activity import org.mariotaku.twidere.extension.model.toLite import org.mariotaku.twidere.extension.model.toSummaryLine @@ -29,13 +30,15 @@ import org.mariotaku.twidere.model.ParcelableActivity import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey -fun Notification.toParcelable(details: AccountDetails): ParcelableActivity { - return toParcelable(details.key).apply { +fun Notification.toParcelable(details: AccountDetails, relationships: Map?): + ParcelableActivity { + return toParcelable(details.key, relationships).apply { account_color = details.color } } -fun Notification.toParcelable(accountKey: UserKey): ParcelableActivity { +fun Notification.toParcelable(accountKey: UserKey, relationships: Map?): + ParcelableActivity { val result = ParcelableActivity() result.account_key = accountKey result.id = "$id-$id" @@ -45,7 +48,7 @@ fun Notification.toParcelable(accountKey: UserKey): ParcelableActivity { result.min_sort_position = result.timestamp result.max_sort_position = result.timestamp - result.sources = toSources(accountKey) + result.sources = toSources(accountKey, relationships) result.user_key = result.sources?.firstOrNull()?.key ?: UserKey("multiple", null) when (type) { @@ -79,8 +82,10 @@ fun Notification.toParcelable(accountKey: UserKey): ParcelableActivity { return result } -private fun Notification.toSources(accountKey: UserKey): Array? { +private fun Notification.toSources(accountKey: UserKey, relationships: Map?): + Array? { val account = this.account ?: return null - return arrayOf(account.toParcelable(accountKey)) + val relationship = relationships?.get(account.id) + return arrayOf(account.toParcelable(accountKey, relationship = relationship)) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableActivityUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableActivityUtils.kt index f3806a0b5..59a472f89 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableActivityUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableActivityUtils.kt @@ -1,6 +1,5 @@ package org.mariotaku.twidere.model.util -import org.mariotaku.twidere.model.ParcelableActivity import org.mariotaku.twidere.model.ParcelableLiteUser import org.mariotaku.twidere.model.UserKey @@ -15,42 +14,25 @@ object ParcelableActivityUtils { /** * @param activity Activity for processing * * - * @param filteredUserKeys Those ids will be removed from source_ids. + * @param filtered Those ids will be removed from source_ids. * * * @param followingOnly Limit following users in sources * * * @return true if source ids changed, false otherwise */ - fun initAfterFilteredSourceIds(activity: ParcelableActivity, filteredUserKeys: Array, - followingOnly: Boolean): Boolean { - if (activity.sources == null) return false - if (activity.after_filtered_source_keys != null) return false - if (followingOnly || filteredUserKeys.isNotEmpty()) { - val list = activity.sources.filter { user -> - if (followingOnly && !user.is_following) { - return@filter false - } + fun filterSources(sources: Array?, filtered: Array?, + followingOnly: Boolean): Array? { + return sources?.filterNot { user -> + if (filtered != null && user.key in filtered) { + return@filterNot true + } - if (!filteredUserKeys.contains(user.key)) { - return@filter true - } - return@filter false - }.map { it.key } - activity.after_filtered_source_keys = list.toTypedArray() - return true - } else { - activity.after_filtered_source_keys = activity.source_keys - return false - } - } - - fun getAfterFilteredSources(activity: ParcelableActivity): Array { - val sources = activity.sources_lite ?: return emptyArray() - val afterFilteredKeys = activity.after_filtered_source_keys?.takeIf { - it.size != sources.size - } ?: return sources - return sources.filter { it.key in afterFilteredKeys }.toTypedArray() + if (followingOnly && !user.is_following) { + return@filterNot true + } + return@filterNot false + }?.toTypedArray() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesAboutMeTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesAboutMeTask.kt index de9387d22..eecafbb37 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesAboutMeTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesAboutMeTask.kt @@ -21,6 +21,7 @@ package org.mariotaku.twidere.task.twitter import android.content.Context import android.net.Uri +import android.support.v4.util.ArraySet import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.mastodon.Mastodon @@ -29,6 +30,7 @@ import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.twidere.R import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.ReadPositionTag +import org.mariotaku.twidere.extension.api.batchGetRelationships 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 @@ -60,9 +62,23 @@ class GetActivitiesAboutMeTask(context: Context) : GetActivitiesTask(context) { when (account.type) { AccountType.MASTODON -> { val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java) - return mastodon.getNotifications(paging).map { - it.toParcelable(account) + val notifications = mastodon.getNotifications(paging) + val allUsers = notifications.flatMap { + val user = it.account + val statusUser = it.status?.account + return@flatMap when { + user != null && statusUser != null -> listOf(user, statusUser) + user != null -> listOf(user) + statusUser != null -> listOf(statusUser) + else -> emptyList() + } } + val userIds = allUsers.mapTo(ArraySet()) { it.id } + val relationships = mastodon.batchGetRelationships(userIds) + val activities = notifications.map { + it.toParcelable(account, relationships) + } + return activities } AccountType.TWITTER -> { val microBlog = account.newMicroBlogInstance(context, MicroBlog::class.java) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt index 363b13482..3b70be901 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt @@ -207,9 +207,9 @@ class ContentNotificationManager( if (FilterQueryBuilder.isFiltered(cr, activity)) { return@forEachRow false } - ParcelableActivityUtils.initAfterFilteredSourceIds(activity, filteredUserKeys, - pref.isNotificationFollowingOnly) - val sources = ParcelableActivityUtils.getAfterFilteredSources(activity) + val sources = ParcelableActivityUtils.filterSources(activity.sources_lite, + filteredUserKeys, pref.isNotificationFollowingOnly) ?: activity.sources_lite + ?: return@forEachRow false if (sources.isEmpty()) return@forEachRow false diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.kt index dbc1ff016..5bdf60751 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/ActivityTitleSummaryViewHolder.kt @@ -33,7 +33,6 @@ import org.mariotaku.twidere.extension.loadProfileImage import org.mariotaku.twidere.model.ActivityTitleSummaryMessage import org.mariotaku.twidere.model.ParcelableActivity import org.mariotaku.twidere.model.ParcelableLiteUser -import org.mariotaku.twidere.model.util.ParcelableActivityUtils import org.mariotaku.twidere.view.BadgeView import org.mariotaku.twidere.view.IconActionView import org.mariotaku.twidere.view.ProfileImageView @@ -80,7 +79,12 @@ class ActivityTitleSummaryViewHolder( fun displayActivity(activity: ParcelableActivity) { val context = adapter.context - val sources = ParcelableActivityUtils.getAfterFilteredSources(activity) + val sources = (activity.after_filtered_sources ?: activity.sources_lite).takeIf { + it.isNotEmpty() + } ?: run { + showNotSupported() + return + } val message = ActivityTitleSummaryMessage.get(context, adapter.userColorNameManager, activity, sources, activityTypeView.defaultColor, adapter.useStarsForLikes, adapter.isNameFirst)