1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-07 23:38:40 +01:00

improved status timeline

This commit is contained in:
Mariotaku Lee 2017-02-28 14:35:31 +08:00
parent bc80d64dce
commit a01cef7a3b
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
14 changed files with 200 additions and 168 deletions

View File

@ -10,7 +10,7 @@ inline fun <T> configure(receiver: T, block: T.() -> Unit): T {
}
fun rangeOfSize(start: Int, size: Int): IntRange {
return IntRange(start, start + size)
return start until start + size
}
fun LongArray.toStringArray(): Array<String> {

View File

@ -227,7 +227,8 @@ class ParcelableActivitiesAdapter(
ITEM_VIEW_TYPE_STATUS -> {
val status = getActivity(position)?.getActivityStatus() ?: return
val statusViewHolder = holder as IStatusViewHolder
statusViewHolder.displayStatus(status, true, true)
statusViewHolder.displayStatus(status = status, displayInReplyTo = true,
displayExtraType = true)
}
ITEM_VIEW_TYPE_TITLE_SUMMARY -> {
bindTitleSummaryViewHolder(holder as ActivityTitleSummaryViewHolder, position)
@ -346,7 +347,7 @@ class ParcelableActivitiesAdapter(
fun findPositionBySortTimestamp(timestamp: Long): Int {
if (timestamp <= 0) return RecyclerView.NO_POSITION
val range = rangeOfSize(activityStartIndex, activityCount - 1)
val range = rangeOfSize(activityStartIndex, activityCount)
if (range.isEmpty()) return RecyclerView.NO_POSITION
if (timestamp < getTimestamp(range.last)) {
return range.last

View File

@ -102,17 +102,38 @@ abstract class ParcelableStatusesAdapter(
set(value) {
field = value
value?.forEach { it.is_pinned_status = true }
updateItemCount()
notifyDataSetChanged()
}
private var data: List<ParcelableStatus>? = null
private var displayPositions: IntArray? = null
private var displayDataCount: Int = 0
private var showingActionCardId = RecyclerView.NO_ID
private var lastItemFiltered: Boolean = false
override val itemCounts = ItemCounts(4)
protected abstract val progressViewIds: IntArray
val statusStartIndex: Int
get() = getItemStartPosition(ITEM_INDEX_STATUS)
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()
}
init {
mediaLoadingHandler = MediaLoadingHandler(*progressViewIds)
val handler = StatusAdapterLinkClickHandler<List<ParcelableStatus>>(context, preferences)
@ -134,47 +155,78 @@ abstract class ParcelableStatusesAdapter(
val indices = (data as ObjectCursor).indices as ParcelableStatusCursorIndices
return cursor.getShort(indices.is_gap).toInt() == 1
}
return data!![dataPosition].is_gap
return getStatus(position)!!.is_gap
}
override fun getStatus(position: Int): ParcelableStatus? {
when (getItemCountIndex(position)) {
1 -> {
return pinnedStatuses!![position - getItemStartPosition(1)]
}
2 -> {
return data!![position - getItemStartPosition(2)]
}
}
return null
return getStatus(position, getItemCountIndex(position))
}
override val statusCount: Int
get() {
if (data == null) return 0
if (lastItemFiltered) return data!!.size - 1
return data!!.size
}
get() = displayDataCount
override val rawStatusCount: Int
get() = data?.size ?: 0
override fun setData(data: List<ParcelableStatus>?): Boolean {
var changed = true
if (data == null) {
displayPositions = null
displayDataCount = 0
} else if (data is ObjectCursor) {
displayPositions = null
displayDataCount = data.size
} else {
var filteredCount = 0
displayPositions = IntArray(data.size).apply {
data.forEachIndexed { i, item ->
if (!item.is_gap && item.is_filtered) {
filteredCount++
} else {
this[i - filteredCount] = i
}
}
}
displayDataCount = data.size - filteredCount
changed = data != data
}
this.data = data
gapLoadingIds.clear()
updateItemCount()
notifyDataSetChanged()
return changed
}
fun getData(): List<ParcelableStatus>? {
return data
}
override fun getItemId(position: Int): Long {
return getFieldValue(position, { cursor, indices ->
val accountKey = UserKey.valueOf(cursor.getString(indices.account_key))
val id = cursor.getString(indices.id)
return@getFieldValue ParcelableStatus.calculateHashCode(accountKey, id).toLong()
}, { status ->
return@getFieldValue status.hashCode().toLong()
}, -1L)
val countIndex = getItemCountIndex(position)
when (countIndex) {
ITEM_INDEX_PINNED_STATUS -> {
val status = pinnedStatuses!![position - getItemStartPosition(ITEM_INDEX_PINNED_STATUS)]
val mask = ITEM_INDEX_PINNED_STATUS.toLong() shl 32
return mask + status.hashCode()
}
ITEM_INDEX_STATUS -> return getFieldValue(position, { cursor, indices ->
val accountKey = UserKey.valueOf(cursor.getString(indices.account_key))
val id = cursor.getString(indices.id)
return@getFieldValue ParcelableStatus.calculateHashCode(accountKey, id).toLong()
}, { status ->
return@getFieldValue status.hashCode().toLong()
}, -1L)
else -> return (countIndex.toLong() shl 32) + position
}
}
override fun getStatusId(position: Int): String? {
return getFieldValue<String?>(position, { cursor, indices ->
val def: String? = null
return getFieldValue(position, { cursor, indices ->
return@getFieldValue cursor.getString(indices.id)
}, { status ->
return@getFieldValue status.id
}, null)
}, def)
}
fun getStatusSortId(position: Int): Long {
@ -206,29 +258,12 @@ abstract class ParcelableStatusesAdapter(
}
override fun getAccountKey(position: Int): UserKey? {
val dataPosition = position - getItemStartPosition(2)
if (dataPosition < 0 || dataPosition >= rawStatusCount) return null
if (data is ObjectCursor) {
val cursor = (data as ObjectCursor).cursor
if (!cursor.safeMoveToPosition(dataPosition)) return null
val indices = (data as ObjectCursor).indices as ParcelableStatusCursorIndices
return UserKey.valueOf(cursor.getString(indices.account_key))
}
return data!![dataPosition].account_key
}
override fun setData(data: List<ParcelableStatus>?): Boolean {
var changed = true
if (data is ObjectCursor || data == null || data.isEmpty()) {
lastItemFiltered = false
} else {
lastItemFiltered = data[data.size - 1].is_filtered
changed = data != data
}
this.data = data
gapLoadingIds.clear()
notifyDataSetChanged()
return changed
val def: UserKey? = null
return getFieldValue(position, { cursor, indices ->
return@getFieldValue UserKey.valueOf(cursor.getString(indices.account_key))
}, { status ->
return@getFieldValue status.account_key
}, def)
}
override fun isCardActionsShown(position: Int): Boolean {
@ -252,7 +287,7 @@ abstract class ParcelableStatusesAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
ITEM_VIEW_TYPE_STATUS -> {
VIEW_TYPE_STATUS -> {
return onCreateStatusViewHolder(parent) as RecyclerView.ViewHolder
}
ITEM_VIEW_TYPE_GAP -> {
@ -263,7 +298,7 @@ abstract class ParcelableStatusesAdapter(
val view = inflater.inflate(R.layout.list_item_load_indicator, parent, false)
return LoadIndicatorViewHolder(view)
}
ITEM_VIEW_TYPE_EMPTY -> {
VIEW_TYPE_EMPTY -> {
return EmptyViewHolder(Space(context))
}
}
@ -271,28 +306,43 @@ abstract class ParcelableStatusesAdapter(
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemCountIndex(position)) {
1 -> {
val status = pinnedStatuses!![position - getItemStartPosition(1)]
(holder as IStatusViewHolder).displayStatus(status, isShowInReplyTo)
when (holder.itemViewType) {
VIEW_TYPE_STATUS -> {
val countIdx = getItemCountIndex(position)
val status = getStatus(position, countIdx)!!
(holder as IStatusViewHolder).displayStatus(status, displayInReplyTo = isShowInReplyTo,
displayPinned = countIdx == ITEM_INDEX_PINNED_STATUS)
}
2 -> {
val status = data!![position - getItemStartPosition(2)]
when (holder.itemViewType) {
ITEM_VIEW_TYPE_STATUS -> {
(holder as IStatusViewHolder).displayStatus(status, isShowInReplyTo)
}
ITEM_VIEW_TYPE_GAP -> {
val loading = gapLoadingIds.any { it.accountKey == status.account_key && it.id == status.id }
(holder as GapViewHolder).display(loading)
}
ITEM_VIEW_TYPE_GAP -> {
val status = getStatus(position)!!
val loading = gapLoadingIds.any { it.accountKey == status.account_key && it.id == status.id }
(holder as GapViewHolder).display(loading)
}
}
}
override fun getItemViewType(position: Int): Int {
if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START != 0L && position == 0) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
}
when (getItemCountIndex(position)) {
ITEM_INDEX_LOAD_START_INDICATOR, ITEM_INDEX_LOAD_END_INDICATOR -> {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
}
ITEM_INDEX_PINNED_STATUS -> {
return VIEW_TYPE_STATUS
}
ITEM_INDEX_STATUS -> {
if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP
} else {
return VIEW_TYPE_STATUS
}
}
}
throw AssertionError()
}
protected abstract fun onCreateStatusViewHolder(parent: ViewGroup): IStatusViewHolder
override fun addGapLoadingId(id: ObjectId) {
@ -303,48 +353,14 @@ abstract class ParcelableStatusesAdapter(
gapLoadingIds.remove(id)
}
fun getData(): List<ParcelableStatus>? {
return data
}
fun isStatus(position: Int): Boolean {
return position < statusCount
}
override fun getItemViewType(position: Int): Int {
if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START != 0L && position == 0) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
}
when (getItemCountIndex(position)) {
0, 3 -> {
return ITEM_VIEW_TYPE_LOAD_INDICATOR
}
1 -> {
return ITEM_VIEW_TYPE_STATUS
}
2 -> {
if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP
} else if (isFiltered(position)) {
return ITEM_VIEW_TYPE_EMPTY
} else {
return ITEM_VIEW_TYPE_STATUS
}
}
}
throw AssertionError()
}
override fun getItemCount(): Int {
val position = loadMoreIndicatorPosition
itemCounts[0] = if (position and ILoadMoreSupportAdapter.START != 0L) 1 else 0
itemCounts[1] = pinnedStatuses?.size ?: 0
itemCounts[2] = statusCount
itemCounts[3] = if (position and ILoadMoreSupportAdapter.END != 0L) 1 else 0
return itemCounts.itemCount
}
override fun findStatusById(accountKey: UserKey, statusId: String): ParcelableStatus? {
for (i in 0 until statusCount) {
if (accountKey == getAccountKey(i) && statusId == getStatusId(i)) {
@ -354,43 +370,11 @@ abstract class ParcelableStatusesAdapter(
return null
}
val statusStartIndex: Int
get() = getItemStartPosition(2)
private inline fun <T> getFieldValue(
position: Int,
readCursorValueAction: (cursor: Cursor, indices: ParcelableStatusCursorIndices) -> T,
readStatusValueAction: (status: ParcelableStatus) -> T,
defValue: T
): T {
val dataPosition = position - getItemStartPosition(2)
if (dataPosition < 0 || dataPosition >= rawStatusCount) return defValue
if (data is ObjectCursor) {
val cursor = (data as ObjectCursor).cursor
if (!cursor.safeMoveToPosition(dataPosition)) return defValue
val indices = (data as ObjectCursor).indices as ParcelableStatusCursorIndices
return readCursorValueAction(cursor, indices)
}
val status = data!![dataPosition]
return readStatusValueAction(status)
}
private fun isFiltered(position: Int): Boolean {
if (data is ObjectCursor) return false
return getStatus(position)!!.is_filtered
}
companion object {
const val ITEM_VIEW_TYPE_STATUS = 2
const val ITEM_VIEW_TYPE_EMPTY = 3
}
fun findPositionByPositionKey(positionKey: Long): Int {
// Assume statuses are descend sorted by id, so break at first status with id
// lesser equals than read position
if (positionKey <= 0) return RecyclerView.NO_POSITION
val range = rangeOfSize(statusStartIndex, statusCount - 1)
val range = rangeOfSize(statusStartIndex, statusCount)
if (range.isEmpty()) return RecyclerView.NO_POSITION
if (positionKey < getStatusPositionKey(range.last)) {
return range.last
@ -402,7 +386,7 @@ abstract class ParcelableStatusesAdapter(
// Assume statuses are descend sorted by id, so break at first status with id
// lesser equals than read position
if (sortId <= 0) return RecyclerView.NO_POSITION
val range = rangeOfSize(statusStartIndex, statusCount - 1)
val range = rangeOfSize(statusStartIndex, statusCount)
if (range.isEmpty()) return RecyclerView.NO_POSITION
if (sortId < getStatusSortId(range.last)) {
return range.last
@ -410,5 +394,59 @@ abstract class ParcelableStatusesAdapter(
return range.indexOfFirst { sortId >= getStatusSortId(it) }
}
private inline fun <T> getFieldValue(
position: Int,
readCursorValueAction: (cursor: Cursor, indices: ParcelableStatusCursorIndices) -> T,
readStatusValueAction: (status: ParcelableStatus) -> T,
defValue: T
): T {
if (data is ObjectCursor) {
val dataPosition = position - getItemStartPosition(ITEM_INDEX_STATUS)
if (dataPosition < 0 || dataPosition >= rawStatusCount) return defValue
val cursor = (data as ObjectCursor).cursor
if (!cursor.safeMoveToPosition(dataPosition)) return defValue
val indices = (data as ObjectCursor).indices as ParcelableStatusCursorIndices
return readCursorValueAction(cursor, indices)
}
return readStatusValueAction(getStatus(position)!!)
}
private fun getStatus(position: Int, countIndex: Int): ParcelableStatus? {
when (countIndex) {
ITEM_INDEX_PINNED_STATUS -> {
return pinnedStatuses!![position - getItemStartPosition(ITEM_INDEX_PINNED_STATUS)]
}
ITEM_INDEX_STATUS -> {
val data = this.data!!
val dataPosition = position - getItemStartPosition(ITEM_INDEX_STATUS)
val positions = displayPositions
if (positions != null) {
return data[positions[dataPosition]]
} else {
return data[dataPosition]
}
}
}
return null
}
private fun updateItemCount() {
val position = loadMoreIndicatorPosition
itemCounts[ITEM_INDEX_LOAD_START_INDICATOR] = if (position and ILoadMoreSupportAdapter.START != 0L) 1 else 0
itemCounts[ITEM_INDEX_PINNED_STATUS] = pinnedStatuses?.size ?: 0
itemCounts[ITEM_INDEX_STATUS] = statusCount
itemCounts[ITEM_INDEX_LOAD_END_INDICATOR] = if (position and ILoadMoreSupportAdapter.END != 0L) 1 else 0
}
companion object {
const val VIEW_TYPE_STATUS = 2
const val VIEW_TYPE_EMPTY = 3
const val ITEM_INDEX_LOAD_START_INDICATOR = 0
const val ITEM_INDEX_PINNED_STATUS = 1
const val ITEM_INDEX_STATUS = 2
const val ITEM_INDEX_LOAD_END_INDICATOR = 3
}
}

View File

@ -72,7 +72,8 @@ class StaggeredGridParcelableStatusesAdapter(context: Context) : ParcelableStatu
}
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean, shouldDisplayExtraType: Boolean) {
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
displayExtraType: Boolean, displayPinned: Boolean) {
val loader = adapter.mediaLoader
val media = status.media ?: return
if (media.isEmpty()) return

View File

@ -56,7 +56,8 @@ class VariousItemsAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerVie
val obj = getItem(position)
when (holder.itemViewType) {
VIEW_TYPE_STATUS -> {
(holder as StatusViewHolder).displayStatus(obj as ParcelableStatus, true)
(holder as StatusViewHolder).displayStatus(obj as ParcelableStatus,
displayInReplyTo = true)
}
VIEW_TYPE_USER -> {
(holder as UserViewHolder).displayUser(obj as ParcelableUser)

View File

@ -238,7 +238,7 @@ abstract class AbsActivitiesFragment protected constructor() :
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
wasAtTop = firstVisibleItemPosition == 0
val activityRange = rangeOfSize(adapter.activityStartIndex, Math.max(0, adapter.activityCount - 1))
val activityRange = rangeOfSize(adapter.activityStartIndex, Math.max(0, adapter.activityCount))
val lastReadPosition = if (loadMore || readFromBottom) {
lastVisibleItemPosition
} else {

View File

@ -282,7 +282,7 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
wasAtTop = firstVisibleItemPosition == 0
val statusRange = rangeOfSize(adapter.statusStartIndex, adapter.statusCount - 1)
val statusRange = rangeOfSize(adapter.statusStartIndex, adapter.statusCount)
val lastReadPosition = if (loadMore || readFromBottom) {
lastVisibleItemPosition
} else {
@ -405,9 +405,9 @@ abstract class AbsStatusesFragment : AbsContentListRecyclerViewFragment<Parcelab
val itemViewType = adapter.getItemViewType(position)
var nextItemIsStatus = false
if (position < adapter.itemCount - 1) {
nextItemIsStatus = adapter.getItemViewType(position + 1) == ParcelableStatusesAdapter.ITEM_VIEW_TYPE_STATUS
nextItemIsStatus = adapter.getItemViewType(position + 1) == ParcelableStatusesAdapter.VIEW_TYPE_STATUS
}
if (nextItemIsStatus && itemViewType == ParcelableStatusesAdapter.ITEM_VIEW_TYPE_STATUS) {
if (nextItemIsStatus && itemViewType == ParcelableStatusesAdapter.VIEW_TYPE_STATUS) {
rect.left = decorPaddingLeft
} else {
rect.left = 0

View File

@ -151,9 +151,9 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
super.onLoadMoreContents(position)
if (position == 0L) return
// Load the last item
val idx = adapter.statusStartIndex + adapter.rawStatusCount - 1
val idx = adapter.rawStatusCount - 1
if (idx < 0) return
val status = adapter.getStatus(idx) ?: return
val status = adapter.getData()?.get(idx) ?: return
val accountKeys = arrayOf(status.account_key)
val maxIds = arrayOf<String?>(status.id)
val param = StatusesRefreshTaskParam(accountKeys, maxIds, null, page + pageDelta)

View File

@ -93,7 +93,7 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
val adapter = DummyItemAdapter(context)
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, itemContent)
holder.displayStatus(status, false, true)
holder.displayStatus(status = status, displayInReplyTo = false, displayExtraType = true)
textCountView.maxLength = TwidereValidator.getTextLimit(details)

View File

@ -1738,8 +1738,8 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
// useful to indicate whether first tweet has reply or not
// We only display that indicator for first conversation item
val itemType = getItemType(position)
statusHolder.displayStatus(status!!, itemType == ITEM_IDX_CONVERSATION
&& position - getItemTypeStart(position) == 0)
val displayInReplyTo = itemType == ITEM_IDX_CONVERSATION && position - getItemTypeStart(position) == 0
statusHolder.displayStatus(status = status!!, displayInReplyTo = displayInReplyTo)
}
VIEW_TYPE_REPLY_ERROR -> {
val errorHolder = holder as StatusErrorItemViewHolder

View File

@ -76,13 +76,13 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
adapter.notifyDataSetChanged()
}
R.id.select_all -> {
for (idx in rangeOfSize(adapter.userStartIndex, adapter.userCount - 1)) {
for (idx in rangeOfSize(adapter.userStartIndex, adapter.userCount)) {
adapter.setItemChecked(idx, true)
}
adapter.notifyDataSetChanged()
}
R.id.invert_selection -> {
for (idx in rangeOfSize(adapter.userStartIndex, adapter.userCount - 1)) {
for (idx in rangeOfSize(adapter.userStartIndex, adapter.userCount)) {
adapter.setItemChecked(idx, !adapter.isItemChecked(idx))
}
adapter.notifyDataSetChanged()
@ -184,7 +184,7 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<Se
Loader<List<ParcelableUser>?>
private fun performImport(filterEverywhere: Boolean) {
val selectedUsers = rangeOfSize(adapter.userStartIndex, adapter.userCount - 1)
val selectedUsers = rangeOfSize(adapter.userStartIndex, adapter.userCount)
.filter { adapter.isItemChecked(it) }
.mapNotNull {
val user = adapter.getUser(it) ?: return@mapNotNull null

View File

@ -165,14 +165,7 @@ abstract class MicroBlogAPIStatusesLoader(
val size = array.size
for (i in (0 until size)) {
val status = array[i]
val filtered = shouldFilterStatus(db, status)
if (filtered) {
if (!status.is_gap && i != size - 1) {
data.remove(status)
} else {
status.is_filtered = true
}
}
status.is_filtered = shouldFilterStatus(db, status)
}
if (comparator != null) {
@ -185,9 +178,8 @@ abstract class MicroBlogAPIStatusesLoader(
}
@Throws(MicroBlogException::class)
protected abstract fun getStatuses(microBlog: MicroBlog,
details: AccountDetails,
paging: Paging): List<Status>
protected abstract fun getStatuses(microBlog: MicroBlog, details: AccountDetails,
paging: Paging): List<Status>
@WorkerThread
protected abstract fun shouldFilterStatus(database: SQLiteDatabase, status: ParcelableStatus): Boolean

View File

@ -131,7 +131,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
}
override fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean,
shouldDisplayExtraType: Boolean) {
displayExtraType: Boolean, displayPinned: Boolean) {
val context = itemView.context
val loader = adapter.mediaLoader
@ -150,7 +150,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
val retweetCount: Long
val favoriteCount: Long
if (status.is_pinned_status) {
if (displayPinned && status.is_pinned_status) {
statusInfoLabel.setText(R.string.pinned_status)
statusInfoIcon.setImageResource(R.drawable.ic_activity_action_pinned)
statusInfoLabel.visibility = View.VISIBLE
@ -412,7 +412,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
favoriteCountView.text = null
favoriteCountView.visibility = View.GONE
}
if (shouldDisplayExtraType) {
if (displayExtraType) {
displayExtraTypeIcon(status.card_name, status.media, status.location,
status.place_full_name, status.is_possibly_sensitive)
} else {

View File

@ -34,9 +34,8 @@ import org.mariotaku.twidere.view.CardMediaContainer
*/
interface IStatusViewHolder : CardMediaContainer.OnMediaClickListener {
fun displayStatus(status: ParcelableStatus,
displayInReplyTo: Boolean = true,
shouldDisplayExtraType: Boolean = true)
fun displayStatus(status: ParcelableStatus, displayInReplyTo: Boolean = true,
displayExtraType: Boolean = true, displayPinned: Boolean = false)
val profileImageView: ImageView?