Twidere-App-Android-Twitter.../twidere/src/main/kotlin/org/mariotaku/twidere/adapter/ParcelableActivitiesAdapter.kt

547 lines
22 KiB
Kotlin
Raw Normal View History

2016-06-29 15:47:52 +02:00
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 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.adapter
import android.annotation.SuppressLint
2016-06-29 15:47:52 +02:00
import android.content.Context
2017-04-28 16:34:47 +02:00
import android.database.CursorIndexOutOfBoundsException
2020-01-26 08:35:15 +01:00
import androidx.legacy.widget.Space
import androidx.recyclerview.widget.RecyclerView
2016-06-29 15:47:52 +02:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
2017-03-01 15:12:25 +01:00
import com.bumptech.glide.RequestManager
2017-04-07 13:05:02 +02:00
import org.mariotaku.kpreferences.get
2017-04-28 15:44:45 +02:00
import org.mariotaku.ktextension.contains
import org.mariotaku.ktextension.rangeOfSize
import org.mariotaku.ktextension.safeGetLong
import org.mariotaku.ktextension.safeMoveToPosition
2016-06-29 15:47:52 +02:00
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IActivitiesAdapter
import org.mariotaku.twidere.adapter.iface.IGapSupportedAdapter
import org.mariotaku.twidere.adapter.iface.IItemCountsAdapter
2016-06-29 15:47:52 +02:00
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
2017-04-07 13:05:02 +02:00
import org.mariotaku.twidere.constant.newDocumentApiKey
2017-05-16 04:20:46 +02:00
import org.mariotaku.twidere.exception.UnsupportedCountIndexException
import org.mariotaku.twidere.extension.model.activityStatus
2016-06-29 15:47:52 +02:00
import org.mariotaku.twidere.fragment.CursorActivitiesFragment
2016-12-06 04:08:56 +01:00
import org.mariotaku.twidere.model.*
2017-04-29 08:55:11 +02:00
import org.mariotaku.twidere.model.util.ParcelableActivityUtils
2017-03-31 10:26:56 +02:00
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
2016-06-29 15:47:52 +02:00
import org.mariotaku.twidere.util.IntentUtils
2017-04-29 08:55:11 +02:00
import org.mariotaku.twidere.util.JsonSerializer
2016-06-29 15:47:52 +02:00
import org.mariotaku.twidere.util.OnLinkClickHandler
import org.mariotaku.twidere.util.TwidereLinkify
import org.mariotaku.twidere.view.holder.*
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
import java.lang.ref.WeakReference
2016-12-06 04:08:56 +01:00
import java.util.*
2016-06-29 15:47:52 +02:00
/**
* Created by mariotaku on 15/1/3.
*/
2016-07-04 03:31:17 +02:00
class ParcelableActivitiesAdapter(
2017-03-01 15:12:25 +01:00
context: Context,
2017-03-02 07:59:19 +01:00
requestManager: RequestManager
) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context, requestManager),
IActivitiesAdapter<List<ParcelableActivity>>, IItemCountsAdapter {
override val itemCounts: ItemCounts = ItemCounts(2)
2016-06-29 15:47:52 +02:00
override var loadMoreIndicatorPosition: Long
get() = super.loadMoreIndicatorPosition
set(value) {
super.loadMoreIndicatorPosition = value
updateItemCount()
}
override var loadMoreSupportedPosition: Long
get() = super.loadMoreSupportedPosition
set(value) {
super.loadMoreSupportedPosition = value
updateItemCount()
}
2017-04-28 15:44:45 +02:00
override val activityEventListener: IActivitiesAdapter.ActivityEventListener?
get() = eventListener
override val gapClickListener: IGapSupportedAdapter.GapClickListener?
get() = eventListener
override val mediaPreviewStyle: Int
get() = statusAdapterDelegate.mediaPreviewStyle
override val useStarsForLikes: Boolean
get() = statusAdapterDelegate.useStarsForLikes
override val mediaPreviewEnabled: Boolean
get() = statusAdapterDelegate.mediaPreviewEnabled
override val lightFont: Boolean
get() = statusAdapterDelegate.lightFont
override var showAccountsColor: Boolean
get() = statusAdapterDelegate.showAccountsColor
set(value) {
statusAdapterDelegate.showAccountsColor = value
notifyDataSetChanged()
}
val isNameFirst: Boolean
get() = statusAdapterDelegate.nameFirst
val activityStartIndex: Int
get() = getItemStartPosition(ITEM_INDEX_ACTIVITY)
var followingOnly: Boolean = false
set(value) {
field = value
notifyDataSetChanged()
}
var mentionsOnly: Boolean = false
set(value) {
field = value
notifyDataSetChanged()
}
private val inflater = LayoutInflater.from(context)
private val twidereLinkify = TwidereLinkify(OnLinkClickHandler(context, null, preferences))
private val statusAdapterDelegate = DummyItemAdapter(context, twidereLinkify, this, requestManager)
private val eventListener: EventListener
private var data: List<ParcelableActivity>? = null
private var activityAdapterListener: ActivityAdapterListener? = null
private var filteredUserKeys: Array<UserKey>? = null
2017-09-15 09:18:33 +02:00
private var filteredUserNames: Array<String>? = null
private var filteredUserDescriptions: Array<String>? = null
2017-04-28 15:44:45 +02:00
private val gapLoadingIds: MutableSet<ObjectId> = HashSet()
private val reuseActivity = ParcelableActivity()
2017-04-29 08:55:11 +02:00
private var infoCache: Array<ActivityInfo?>? = null
2017-04-28 15:44:45 +02:00
2016-06-29 15:47:52 +02:00
init {
eventListener = EventListener(this)
statusAdapterDelegate.updateOptions()
2017-04-29 08:55:11 +02:00
setHasStableIds(true)
2016-06-29 15:47:52 +02:00
}
override fun isGapItem(position: Int): Boolean {
2017-04-29 08:55:11 +02:00
return getFieldValue(position, readInfoValueAction = {
it.gap
}, readStatusValueAction = { activity ->
activity.is_gap
}, defValue = false, raw = false)
2016-06-29 15:47:52 +02:00
}
override fun getItemId(position: Int): Long {
2020-06-08 23:19:10 +02:00
return when (val countIndex = itemCounts.getItemCountIndex(position)) {
ITEM_INDEX_ACTIVITY -> {
2020-06-08 23:19:10 +02:00
getRowId(position, false)
}
else -> {
2020-06-08 23:19:10 +02:00
(countIndex.toLong() shl 32) or getItemViewType(position).toLong()
}
2016-06-29 15:47:52 +02:00
}
}
override fun getActivity(position: Int, raw: Boolean): ParcelableActivity {
2017-04-28 15:44:45 +02:00
return getActivityInternal(position, raw, false)
2016-06-29 15:47:52 +02:00
}
override fun getActivityCount(raw: Boolean): Int {
if (data == null) return 0
return data!!.size
}
2016-06-29 15:47:52 +02:00
override fun setData(data: List<ParcelableActivity>?) {
if (data is CursorActivitiesFragment.CursorActivitiesLoader.ActivityCursor) {
2017-04-12 14:58:08 +02:00
filteredUserKeys = data.filteredUserIds
2017-09-15 09:18:33 +02:00
filteredUserNames = data.filteredUserNames
filteredUserDescriptions = data.filteredUserDescriptions
2016-06-29 15:47:52 +02:00
}
this.data = data
2017-07-16 08:09:46 +02:00
this.infoCache = if (data != null) arrayOfNulls(data.size) else null
2016-12-06 04:08:56 +01:00
gapLoadingIds.clear()
updateItemCount()
2016-06-29 15:47:52 +02:00
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
ITEM_VIEW_TYPE_STATUS -> {
val holder = ListParcelableStatusesAdapter.createStatusViewHolder(statusAdapterDelegate,
inflater, parent)
holder.setStatusClickListener(eventListener)
return holder
}
ITEM_VIEW_TYPE_TITLE_SUMMARY -> {
val view = inflater.inflate(R.layout.list_item_activity_summary_compact, parent, false)
2017-01-07 15:45:33 +01:00
val holder = ActivityTitleSummaryViewHolder(view, this)
2016-06-29 15:47:52 +02:00
holder.setOnClickListeners()
2017-01-07 15:45:33 +01:00
holder.setupViewOptions()
2016-06-29 15:47:52 +02:00
return holder
}
ITEM_VIEW_TYPE_GAP -> {
2016-12-06 04:08:56 +01:00
val view = inflater.inflate(GapViewHolder.layoutResource, parent, false)
2016-06-29 15:47:52 +02:00
return GapViewHolder(this, view)
}
ITEM_VIEW_TYPE_LOAD_INDICATOR -> {
2017-01-31 14:10:20 +01:00
val view = inflater.inflate(R.layout.list_item_load_indicator, parent, false)
2016-06-29 15:47:52 +02:00
return LoadIndicatorViewHolder(view)
}
ITEM_VIEW_TYPE_STUB -> {
val view = inflater.inflate(R.layout.list_item_two_line, parent, false)
return StubViewHolder(view)
}
ITEM_VIEW_TYPE_EMPTY -> {
return EmptyViewHolder(Space(context))
}
}
2020-06-08 23:07:20 +02:00
throw UnsupportedOperationException("Unsupported viewType $viewType")
2016-06-29 15:47:52 +02:00
}
2017-04-28 15:44:45 +02:00
2016-06-29 15:47:52 +02:00
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
2016-08-19 16:25:27 +02:00
when (holder.itemViewType) {
2016-06-29 15:47:52 +02:00
ITEM_VIEW_TYPE_STATUS -> {
2017-04-28 15:44:45 +02:00
val activity = getActivityInternal(position, raw = false, reuse = true)
(holder as IStatusViewHolder).display(activity, displayInReplyTo = true)
2016-06-29 15:47:52 +02:00
}
ITEM_VIEW_TYPE_TITLE_SUMMARY -> {
2017-04-28 15:44:45 +02:00
val activity = getActivityInternal(position, raw = false, reuse = true)
2017-04-29 08:55:11 +02:00
val sources = getAfterFilteredSources(position, false)
activity.after_filtered_sources = sources
2017-04-28 15:44:45 +02:00
(holder as ActivityTitleSummaryViewHolder).displayActivity(activity)
2016-06-29 15:47:52 +02:00
}
ITEM_VIEW_TYPE_STUB -> {
2017-04-28 15:44:45 +02:00
val activity = getActivityInternal(position, raw = false, reuse = true)
(holder as StubViewHolder).displayActivity(activity)
2016-06-29 15:47:52 +02:00
}
2016-12-06 04:08:56 +01:00
ITEM_VIEW_TYPE_GAP -> {
2017-04-28 15:44:45 +02:00
val activity = getActivityInternal(position, raw = false, reuse = true)
2017-02-04 15:47:50 +01:00
val loading = gapLoadingIds.any { it.accountKey == activity.account_key && it.id == activity.id }
2016-12-06 04:08:56 +01:00
(holder as GapViewHolder).display(loading)
}
2016-06-29 15:47:52 +02:00
}
}
override fun getItemViewType(position: Int): Int {
2020-06-08 23:09:07 +02:00
when (val countIndex = getItemCountIndex(position)) {
ITEM_INDEX_ACTIVITY -> {
if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP
2016-06-29 15:47:52 +02:00
}
2020-06-08 23:09:07 +02:00
when (getAction(position)) {
2017-04-28 15:44:45 +02:00
Activity.Action.MENTION, Activity.Action.QUOTE, Activity.Action.REPLY -> {
return ITEM_VIEW_TYPE_STATUS
}
Activity.Action.FOLLOW, Activity.Action.FAVORITE, Activity.Action.RETWEET,
Activity.Action.FAVORITED_RETWEET, Activity.Action.RETWEETED_RETWEET,
Activity.Action.RETWEETED_MENTION, Activity.Action.FAVORITED_MENTION,
Activity.Action.LIST_CREATED, Activity.Action.LIST_MEMBER_ADDED,
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
2017-04-29 08:55:11 +02:00
val afterFiltered = getAfterFilteredSources(position, false)
if (afterFiltered != null && afterFiltered.isEmpty()) {
return ITEM_VIEW_TYPE_EMPTY
}
return ITEM_VIEW_TYPE_TITLE_SUMMARY
2016-08-17 15:12:47 +02:00
}
2016-06-29 15:47:52 +02:00
}
return ITEM_VIEW_TYPE_STUB
}
ITEM_INDEX_LOAD_MORE_INDICATOR -> {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
2016-06-29 15:47:52 +02:00
}
2017-05-16 04:20:46 +02:00
else -> throw UnsupportedCountIndexException(countIndex, position)
2016-06-29 15:47:52 +02:00
}
}
2016-12-06 04:08:56 +01:00
override fun addGapLoadingId(id: ObjectId) {
gapLoadingIds.add(id)
}
override fun removeGapLoadingId(id: ObjectId) {
gapLoadingIds.remove(id)
}
2016-06-29 15:47:52 +02:00
override fun getItemCount(): Int {
return itemCounts.itemCount
2016-06-29 15:47:52 +02:00
}
fun setListener(listener: ActivityAdapterListener) {
activityAdapterListener = listener
}
fun isActivity(position: Int, raw: Boolean = false): Boolean {
return position < getActivityCount(raw)
2016-06-29 15:47:52 +02:00
}
fun findPositionBySortTimestamp(timestamp: Long, raw: Boolean = false): Int {
2017-02-09 07:34:50 +01:00
if (timestamp <= 0) return RecyclerView.NO_POSITION
val range = rangeOfSize(activityStartIndex, getActivityCount(raw))
2017-02-09 07:34:50 +01:00
if (range.isEmpty()) return RecyclerView.NO_POSITION
2017-04-03 08:37:51 +02:00
if (timestamp < getTimestamp(range.last, raw)) {
2017-02-09 07:34:50 +01:00
return range.last
}
2017-04-03 08:37:51 +02:00
return range.indexOfFirst { timestamp >= getTimestamp(it, raw) }
2016-12-24 14:07:11 +01:00
}
2017-04-28 16:34:47 +02:00
fun getTimestamp(adapterPosition: Int, raw: Boolean = false): Long {
2017-04-29 08:55:11 +02:00
return getFieldValue(adapterPosition, readInfoValueAction = {
it.timestamp
2017-04-28 16:34:47 +02:00
}, readStatusValueAction = { activity ->
activity.timestamp
}, defValue = -1, raw = raw)
}
fun getAction(adapterPosition: Int, raw: Boolean = false): String? {
2017-04-29 08:55:11 +02:00
return getFieldValue(adapterPosition, readInfoValueAction = {
it.action
2017-04-28 16:34:47 +02:00
}, readStatusValueAction = { activity ->
activity.action
}, defValue = null, raw = raw)
}
2017-04-28 17:25:44 +02:00
fun getRowId(adapterPosition: Int, raw: Boolean = false): Long {
2017-04-29 08:55:11 +02:00
return getFieldValue(adapterPosition, readInfoValueAction = {
it._id
2017-04-28 17:25:44 +02:00
}, readStatusValueAction = { activity ->
2017-04-29 08:55:11 +02:00
activity.hashCode().toLong()
2017-04-28 17:25:44 +02:00
}, defValue = -1L, raw = raw)
}
2017-04-28 16:34:47 +02:00
fun getData(): List<ParcelableActivity>? {
return data
}
private fun updateItemCount() {
itemCounts[0] = getActivityCount(false)
itemCounts[1] = if (ILoadMoreSupportAdapter.END in loadMoreIndicatorPosition) 1 else 0
}
2017-04-28 15:44:45 +02:00
private fun getActivityInternal(position: Int, raw: Boolean, reuse: Boolean): ParcelableActivity {
val dataPosition = position - activityStartIndex
val activityCount = getActivityCount(raw)
if (dataPosition < 0 || dataPosition >= activityCount) {
val validRange = rangeOfSize(activityStartIndex, getActivityCount(raw))
throw IndexOutOfBoundsException("index: $position, valid range is $validRange")
}
val data = this.data!!
2020-06-08 23:19:10 +02:00
return if (reuse && data is ObjectCursor) {
2017-04-28 15:44:45 +02:00
val activity = data.setInto(dataPosition, reuseActivity)
2017-04-29 08:55:11 +02:00
activity.after_filtered_sources = null
2020-06-08 23:19:10 +02:00
activity
2017-04-28 15:44:45 +02:00
} else {
2020-06-08 23:19:10 +02:00
data[dataPosition]
2017-04-28 15:44:45 +02:00
}
}
2017-04-29 08:55:11 +02:00
private fun getAfterFilteredSources(position: Int, raw: Boolean): Array<ParcelableLiteUser>? {
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,
2017-09-15 09:18:33 +02:00
filteredUserKeys, filteredUserNames, filteredUserDescriptions, followingOnly)
2017-04-29 08:55:11 +02:00
activity.after_filtered_sources = sources
return@lambda2 sources
}, defValue = null, raw = raw)
2017-04-29 05:19:31 +02:00
}
2017-04-28 16:34:47 +02:00
private inline fun <T> getFieldValue(position: Int,
2017-04-29 08:55:11 +02:00
readInfoValueAction: (ActivityInfo) -> T,
2017-04-28 16:34:47 +02:00
readStatusValueAction: (status: ParcelableActivity) -> T,
defValue: T, raw: Boolean = false): T {
2017-05-18 17:20:42 +02:00
val data = this.data
2017-04-28 16:34:47 +02:00
if (data is ObjectCursor) {
val dataPosition = position - activityStartIndex
if (dataPosition < 0 || dataPosition >= getActivityCount(true)) {
throw CursorIndexOutOfBoundsException("index: $position, valid range is $0..${getActivityCount(true)}")
}
2017-04-29 08:55:11 +02:00
val info = infoCache?.get(dataPosition) ?: run {
2017-06-01 11:21:34 +02:00
val cursor = data.cursor
if (!cursor.safeMoveToPosition(dataPosition)) return defValue
val indices = data.indices
2017-04-29 08:55:11 +02:00
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,
2017-09-15 09:18:33 +02:00
filteredUserNames, filteredUserDescriptions, followingOnly)
2017-04-29 08:55:11 +02:00
val newInfo = ActivityInfo(_id, timestamp, gap, action, filteredSources)
infoCache?.set(dataPosition, newInfo)
return@run newInfo
}
return readInfoValueAction(info)
2017-04-28 16:34:47 +02:00
}
return readStatusValueAction(getActivityInternal(position, raw, false))
}
2016-06-29 15:47:52 +02:00
interface ActivityAdapterListener {
fun onGapClick(holder: GapViewHolder, position: Int)
fun onActivityClick(holder: ActivityTitleSummaryViewHolder, position: Int)
fun onStatusActionClick(holder: IStatusViewHolder, id: Int, position: Int)
fun onStatusActionLongClick(holder: IStatusViewHolder, id: Int, position: Int): Boolean
2016-06-29 15:47:52 +02:00
fun onStatusMenuClick(holder: IStatusViewHolder, menuView: View, position: Int)
fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, position: Int)
fun onStatusClick(holder: IStatusViewHolder, position: Int)
2017-01-17 18:59:44 +01:00
fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int)
2016-06-29 15:47:52 +02:00
}
internal class StubViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
2017-06-19 06:11:28 +02:00
internal val text1 = itemView.findViewById<TextView>(android.R.id.text1)
internal val text2 = itemView.findViewById<TextView>(android.R.id.text2)
2016-06-29 15:47:52 +02:00
init {
2020-06-08 23:07:20 +02:00
text2.isSingleLine = false
2016-06-29 15:47:52 +02:00
}
@SuppressLint("SetTextI18n")
2016-06-29 15:47:52 +02:00
fun displayActivity(activity: ParcelableActivity) {
text1.text = text1.resources.getString(R.string.unsupported_activity_action_title,
activity.action)
2017-04-28 15:44:45 +02:00
text2.text = "host: ${activity.account_key.host}, id: ${activity.id}\n"
2016-08-30 17:57:37 +02:00
text2.append(itemView.context.getString(R.string.unsupported_activity_action_summary))
2016-06-29 15:47:52 +02:00
}
}
2017-04-28 15:44:45 +02:00
internal class EventListener(adapter: ParcelableActivitiesAdapter) :
IStatusViewHolder.StatusClickListener, IGapSupportedAdapter.GapClickListener,
IActivitiesAdapter.ActivityEventListener {
2016-06-29 15:47:52 +02:00
2017-01-20 15:08:42 +01:00
val adapterRef = WeakReference(adapter)
2016-06-29 15:47:52 +02:00
override fun onGapClick(holder: GapViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
val activity = adapter.getActivity(position)
2016-12-06 04:08:56 +01:00
adapter.addGapLoadingId(ObjectId(activity.account_key, activity.id))
adapter.activityAdapterListener?.onGapClick(holder, position)
2016-06-29 15:47:52 +02:00
}
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
val listener = adapterRef.get()?.activityAdapterListener ?: return
listener.onStatusActionClick(holder as IStatusViewHolder, id, position)
}
override fun onItemActionLongClick(holder: RecyclerView.ViewHolder, id: Int, position: Int): Boolean {
val listener = adapterRef.get()?.activityAdapterListener ?: return false
return listener.onStatusActionLongClick(holder as IStatusViewHolder, id, position)
2016-06-29 15:47:52 +02:00
}
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
2016-08-09 09:48:16 +02:00
return true
2016-06-29 15:47:52 +02:00
}
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
2017-04-28 15:44:45 +02:00
val status = adapter.getActivity(position).activityStatus ?: return
2016-06-29 15:47:52 +02:00
IntentUtils.openUserProfile(adapter.context, status.account_key, status.user_key,
2017-04-07 13:05:02 +02:00
status.user_screen_name, status.extras?.user_statusnet_profile_url,
2017-08-28 06:31:19 +02:00
adapter.preferences[newDocumentApiKey], null)
2016-06-29 15:47:52 +02:00
}
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
2017-01-17 18:59:44 +01:00
adapter.activityAdapterListener?.onStatusClick(holder, position)
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
adapter.activityAdapterListener?.onQuotedStatusClick(holder, position)
2016-06-29 15:47:52 +02:00
}
2017-02-28 03:37:03 +01:00
override fun onMediaClick(holder: IStatusViewHolder, view: View, current: ParcelableMedia, statusPosition: Int) {
2016-06-29 15:47:52 +02:00
val adapter = adapterRef.get() ?: return
2017-02-28 03:37:03 +01:00
adapter.activityAdapterListener?.onMediaClick(holder, view, current, statusPosition)
2016-06-29 15:47:52 +02:00
}
override fun onActivityClick(holder: ActivityTitleSummaryViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
2017-01-17 18:59:44 +01:00
adapter.activityAdapterListener?.onActivityClick(holder, position)
2016-06-29 15:47:52 +02:00
}
override fun onItemMenuClick(holder: RecyclerView.ViewHolder, menuView: View, position: Int) {
val adapter = adapterRef.get() ?: return
2017-01-17 18:59:44 +01:00
adapter.activityAdapterListener?.onStatusMenuClick(holder as StatusViewHolder, menuView, position)
2016-06-29 15:47:52 +02:00
}
}
2017-04-29 08:55:11 +02:00
data class ActivityInfo(
val _id: Long,
val timestamp: Long,
val gap: Boolean,
val action: String,
val filteredSources: Array<ParcelableLiteUser>?
2017-09-15 09:18:33 +02:00
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ActivityInfo
if (_id != other._id) return false
if (timestamp != other.timestamp) return false
if (gap != other.gap) return false
if (action != other.action) return false
if (!Arrays.equals(filteredSources, other.filteredSources)) return false
return true
}
override fun hashCode(): Int {
var result = _id.hashCode()
result = 31 * result + timestamp.hashCode()
result = 31 * result + gap.hashCode()
result = 31 * result + action.hashCode()
2020-06-09 00:50:51 +02:00
result = 31 * result + (filteredSources?.contentHashCode() ?: 0)
2017-09-15 09:18:33 +02:00
return result
}
}
2017-04-29 08:55:11 +02:00
2016-06-29 15:47:52 +02:00
companion object {
2017-02-10 19:01:31 +01:00
const val ITEM_VIEW_TYPE_STUB = 0
const val ITEM_VIEW_TYPE_GAP = 1
const val ITEM_VIEW_TYPE_LOAD_INDICATOR = 2
const val ITEM_VIEW_TYPE_TITLE_SUMMARY = 3
const val ITEM_VIEW_TYPE_STATUS = 4
const val ITEM_VIEW_TYPE_EMPTY = 5
2016-12-24 14:07:11 +01:00
const val ITEM_INDEX_ACTIVITY = 0
const val ITEM_INDEX_LOAD_MORE_INDICATOR = 1
2016-06-29 15:47:52 +02:00
}
}