forked from GitHub-Mirror/riotX-android
Refactoring (duplication in Message Item Factory) + cleaning
This commit is contained in:
parent
297f202005
commit
e22b555b58
@ -46,7 +46,7 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
private val backgroundHandler: Handler = TimelineAsyncHelper.getBackgroundHandler()
|
private val backgroundHandler: Handler = TimelineAsyncHelper.getBackgroundHandler()
|
||||||
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
|
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
|
||||||
|
|
||||||
interface Callback : ReactionPillCallback {
|
interface Callback : ReactionPillCallback, AvatarCallback {
|
||||||
fun onEventVisible(event: TimelineEvent)
|
fun onEventVisible(event: TimelineEvent)
|
||||||
fun onUrlClicked(url: String)
|
fun onUrlClicked(url: String)
|
||||||
fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View)
|
fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View)
|
||||||
@ -55,8 +55,6 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
fun onAudioMessageClicked(messageAudioContent: MessageAudioContent)
|
fun onAudioMessageClicked(messageAudioContent: MessageAudioContent)
|
||||||
fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View)
|
fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View)
|
||||||
fun onEventLongClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View): Boolean
|
fun onEventLongClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View): Boolean
|
||||||
fun onAvatarClicked(informationData: MessageInformationData)
|
|
||||||
fun onMemberNameClicked(informationData: MessageInformationData)
|
|
||||||
fun onEditedDecorationClicked(informationData: MessageInformationData, editAggregatedSummary: EditAggregatedSummary?)
|
fun onEditedDecorationClicked(informationData: MessageInformationData, editAggregatedSummary: EditAggregatedSummary?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +63,11 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
fun onLongClickOnReactionPill(informationData: MessageInformationData, reaction: String)
|
fun onLongClickOnReactionPill(informationData: MessageInformationData, reaction: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AvatarCallback {
|
||||||
|
fun onAvatarClicked(informationData: MessageInformationData)
|
||||||
|
fun onMemberNameClicked(informationData: MessageInformationData)
|
||||||
|
}
|
||||||
|
|
||||||
private val collapsedEventIds = linkedSetOf<String>()
|
private val collapsedEventIds = linkedSetOf<String>()
|
||||||
private val mergeItemCollapseStates = HashMap<String, Boolean>()
|
private val mergeItemCollapseStates = HashMap<String, Boolean>()
|
||||||
private val modelCache = arrayListOf<CacheItemData?>()
|
private val modelCache = arrayListOf<CacheItemData?>()
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.*
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.koin.android.ext.android.get
|
import org.koin.android.ext.android.get
|
||||||
|
|
||||||
|
|
||||||
@ -33,31 +29,20 @@ data class ReactionInfo(
|
|||||||
*/
|
*/
|
||||||
class ViewReactionViewModel(private val session: Session,
|
class ViewReactionViewModel(private val session: Session,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter,
|
private val timelineDateFormatter: TimelineDateFormatter,
|
||||||
lifecycleOwner: LifecycleOwner?,
|
|
||||||
liveSummary: LiveData<List<EventAnnotationsSummary>>?,
|
|
||||||
initialState: DisplayReactionsViewState) : VectorViewModel<DisplayReactionsViewState>(initialState) {
|
initialState: DisplayReactionsViewState) : VectorViewModel<DisplayReactionsViewState>(initialState) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
loadReaction()
|
loadReaction()
|
||||||
if (lifecycleOwner != null) {
|
|
||||||
liveSummary?.observe(lifecycleOwner, Observer {
|
|
||||||
it?.firstOrNull()?.let {
|
|
||||||
loadReaction()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
fun loadReaction() = withState { state ->
|
||||||
|
|
||||||
private fun loadReaction() = withState { state ->
|
|
||||||
|
|
||||||
GlobalScope.launch {
|
|
||||||
try {
|
try {
|
||||||
val room = session.getRoom(state.roomId)
|
val room = session.getRoom(state.roomId)
|
||||||
val event = room?.getTimeLineEvent(state.eventId)
|
val event = room?.getTimeLineEvent(state.eventId)
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
setState { copy(mapReactionKeyToMemberList = Fail(Throwable())) }
|
setState { copy(mapReactionKeyToMemberList = Fail(Throwable())) }
|
||||||
return@launch
|
return@withState
|
||||||
}
|
}
|
||||||
var results = ArrayList<ReactionInfo>()
|
var results = ArrayList<ReactionInfo>()
|
||||||
event.annotations?.reactionsSummary?.forEach { sum ->
|
event.annotations?.reactionsSummary?.forEach { sum ->
|
||||||
@ -81,7 +66,6 @@ class ViewReactionViewModel(private val session: Session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<ViewReactionViewModel, DisplayReactionsViewState> {
|
companion object : MvRxViewModelFactory<ViewReactionViewModel, DisplayReactionsViewState> {
|
||||||
@ -98,7 +82,18 @@ class ViewReactionViewModel(private val session: Session,
|
|||||||
override fun create(viewModelContext: ViewModelContext, state: DisplayReactionsViewState): ViewReactionViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: DisplayReactionsViewState): ViewReactionViewModel? {
|
||||||
val session = viewModelContext.activity.get<Session>()
|
val session = viewModelContext.activity.get<Session>()
|
||||||
val eventId = (viewModelContext.args as TimelineEventFragmentArgs).eventId
|
val eventId = (viewModelContext.args as TimelineEventFragmentArgs).eventId
|
||||||
return ViewReactionViewModel(session, viewModelContext.activity.get(), viewModelContext.activity, session.getRoom(state.roomId)?.getEventSummaryLive(eventId), state)
|
val lifecycleOwner = (viewModelContext as FragmentViewModelContext).fragment<Fragment>()
|
||||||
|
val liveSummary = session.getRoom(state.roomId)?.getEventSummaryLive(eventId)
|
||||||
|
val viewReactionViewModel = ViewReactionViewModel(session, viewModelContext.activity.get(), state)
|
||||||
|
// This states observes the live summary
|
||||||
|
// When fragment context will be destroyed the observer will automatically removed
|
||||||
|
liveSummary?.observe(lifecycleOwner, Observer {
|
||||||
|
it?.firstOrNull()?.let {
|
||||||
|
viewReactionViewModel.loadReaction()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return viewReactionViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,18 +143,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
callback: TimelineEventController.Callback?): MessageFileItem? {
|
callback: TimelineEventController.Callback?): MessageFileItem? {
|
||||||
return MessageFileItem_()
|
return MessageFileItem_()
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.filename(messageContent.body)
|
.filename(messageContent.body)
|
||||||
.iconRes(R.drawable.filetype_audio)
|
.iconRes(R.drawable.filetype_audio)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener {
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener {
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
.cellClickListener(
|
.cellClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view: View ->
|
DebouncedClickListener(View.OnClickListener { view: View ->
|
||||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||||
@ -174,18 +167,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
callback: TimelineEventController.Callback?): MessageFileItem? {
|
callback: TimelineEventController.Callback?): MessageFileItem? {
|
||||||
return MessageFileItem_()
|
return MessageFileItem_()
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.filename(messageContent.body)
|
.filename(messageContent.body)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.iconRes(R.drawable.filetype_attachment)
|
.iconRes(R.drawable.filetype_attachment)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
.cellClickListener(
|
.cellClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||||
@ -223,17 +209,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
return MessageImageVideoItem_()
|
return MessageImageVideoItem_()
|
||||||
.playable(messageContent.info?.mimeType == "image/gif")
|
.playable(messageContent.info?.mimeType == "image/gif")
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.mediaData(data)
|
.mediaData(data)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
.clickListener(
|
.clickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onImageMessageClicked(messageContent, data, view)
|
callback?.onImageMessageClicked(messageContent, data, view)
|
||||||
@ -271,17 +250,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
return MessageImageVideoItem_()
|
return MessageImageVideoItem_()
|
||||||
.playable(true)
|
.playable(true)
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.mediaData(thumbnailData)
|
.mediaData(thumbnailData)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
.cellClickListener(
|
.cellClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||||
@ -316,16 +288,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
//click on the text
|
//click on the text
|
||||||
.clickListener(
|
.clickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
@ -390,12 +355,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
return MessageTextItem_()
|
return MessageTextItem_()
|
||||||
.message(message)
|
.message(message)
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
.memberClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onMemberNameClicked(informationData)
|
callback?.onMemberNameClicked(informationData)
|
||||||
@ -430,16 +392,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
.avatarCallback(callback)
|
||||||
.reactionPillCallback(callback)
|
.reactionPillCallback(callback)
|
||||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||||
.avatarClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
.cellClickListener(
|
.cellClickListener(
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
DebouncedClickListener(View.OnClickListener { view ->
|
||||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||||
@ -454,14 +409,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
callback: TimelineEventController.Callback?): RedactedMessageItem? {
|
callback: TimelineEventController.Callback?): RedactedMessageItem? {
|
||||||
return RedactedMessageItem_()
|
return RedactedMessageItem_()
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
.avatarClickListener(
|
.avatarCallback(callback)
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onAvatarClicked(informationData)
|
|
||||||
}))
|
|
||||||
.memberClickListener(
|
|
||||||
DebouncedClickListener(View.OnClickListener { view ->
|
|
||||||
callback?.onMemberNameClicked(informationData)
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): CharSequence {
|
private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): CharSequence {
|
||||||
|
@ -29,6 +29,7 @@ import androidx.core.view.isGone
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.utils.DebouncedClickListener
|
||||||
import im.vector.riotredesign.core.utils.DimensionUtils.dpToPx
|
import im.vector.riotredesign.core.utils.DimensionUtils.dpToPx
|
||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
@ -45,9 +46,6 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
|||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var cellClickListener: View.OnClickListener? = null
|
var cellClickListener: View.OnClickListener? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
|
||||||
var avatarClickListener: View.OnClickListener? = null
|
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var memberClickListener: View.OnClickListener? = null
|
var memberClickListener: View.OnClickListener? = null
|
||||||
|
|
||||||
@ -57,6 +55,17 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
|||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var reactionPillCallback: TimelineEventController.ReactionPillCallback? = null
|
var reactionPillCallback: TimelineEventController.ReactionPillCallback? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var avatarCallback: TimelineEventController.AvatarCallback?= null
|
||||||
|
|
||||||
|
private val _avatarClickListener = DebouncedClickListener(View.OnClickListener {
|
||||||
|
avatarCallback?.onAvatarClicked(informationData)
|
||||||
|
})
|
||||||
|
private val _memberNameClickListener = DebouncedClickListener(View.OnClickListener {
|
||||||
|
avatarCallback?.onMemberNameClicked(informationData)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
var reactionClickListener: ReactionButton.ReactedListener = object : ReactionButton.ReactedListener {
|
var reactionClickListener: ReactionButton.ReactedListener = object : ReactionButton.ReactedListener {
|
||||||
override fun onReacted(reactionButton: ReactionButton) {
|
override fun onReacted(reactionButton: ReactionButton) {
|
||||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString, true)
|
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString, true)
|
||||||
@ -81,9 +90,9 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
|||||||
width = size
|
width = size
|
||||||
}
|
}
|
||||||
holder.avatarImageView.visibility = View.VISIBLE
|
holder.avatarImageView.visibility = View.VISIBLE
|
||||||
holder.avatarImageView.setOnClickListener(avatarClickListener)
|
holder.avatarImageView.setOnClickListener(_avatarClickListener)
|
||||||
holder.memberNameView.visibility = View.VISIBLE
|
holder.memberNameView.visibility = View.VISIBLE
|
||||||
holder.memberNameView.setOnClickListener(memberClickListener)
|
holder.memberNameView.setOnClickListener(_memberNameClickListener)
|
||||||
holder.timeView.visibility = View.VISIBLE
|
holder.timeView.visibility = View.VISIBLE
|
||||||
holder.timeView.text = informationData.time
|
holder.timeView.text = informationData.time
|
||||||
holder.memberNameView.text = informationData.memberName
|
holder.memberNameView.text = informationData.memberName
|
||||||
|
@ -11,8 +11,10 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/itemSimpleReactionInfoKey"
|
android:id="@+id/itemSimpleReactionInfoKey"
|
||||||
android:layout_width="44dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:textColor="?android:textColorPrimary"
|
android:textColor="?android:textColorPrimary"
|
||||||
|
Loading…
Reference in New Issue
Block a user