forked from GitHub-Mirror/riotX-android
Send reaction view quick react and picker
+ fix / Error when to many reactions in cells (more than placeholders -8-) + fix / DefaultTimeline quick map access was not shifted when items inserted at given index
This commit is contained in:
@ -28,4 +28,8 @@ sealed class RoomDetailActions {
|
||||
data class EventDisplayed(val event: TimelineEvent) : RoomDetailActions()
|
||||
data class LoadMore(val direction: Timeline.Direction) : RoomDetailActions()
|
||||
|
||||
data class SendReaction(val reaction: String, val targetEventId: String) : RoomDetailActions()
|
||||
|
||||
|
||||
|
||||
}
|
@ -107,6 +107,7 @@ data class RoomDetailArgs(
|
||||
private const val CAMERA_VALUE_TITLE = "attachment"
|
||||
private const val REQUEST_FILES_REQUEST_CODE = 0
|
||||
private const val TAKE_IMAGE_REQUEST_CODE = 1
|
||||
private const val REACTION_SELECT_REQUEST_CODE = 2
|
||||
|
||||
class RoomDetailFragment :
|
||||
VectorBaseFragment(),
|
||||
@ -182,6 +183,12 @@ class RoomDetailFragment :
|
||||
if (resultCode == RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
REQUEST_FILES_REQUEST_CODE, TAKE_IMAGE_REQUEST_CODE -> handleMediaIntent(data)
|
||||
REACTION_SELECT_REQUEST_CODE -> {
|
||||
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID) ?: return
|
||||
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT) ?: return
|
||||
//TODO check if already reacted with that?
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction,eventId))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -487,7 +494,8 @@ class RoomDetailFragment :
|
||||
|
||||
when (actionData.actionId) {
|
||||
MessageMenuViewModel.ACTION_ADD_REACTION -> {
|
||||
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext()), 0)
|
||||
val eventId = actionData.data?.toString() ?: return
|
||||
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE)
|
||||
}
|
||||
MessageMenuViewModel.ACTION_COPY -> {
|
||||
//I need info about the current selected message :/
|
||||
@ -539,6 +547,11 @@ class RoomDetailFragment :
|
||||
.setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() }
|
||||
.show()
|
||||
}
|
||||
MessageMenuViewModel.ACTION_QUICK_REACT -> {
|
||||
(actionData.data as? Pair<String, String>)?.let { pairData ->
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(pairData.second, pairData.first))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
@ -69,11 +69,12 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
|
||||
fun process(action: RoomDetailActions) {
|
||||
when (action) {
|
||||
is RoomDetailActions.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailActions.IsDisplayed -> handleIsDisplayed()
|
||||
is RoomDetailActions.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailActions.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailActions.IsDisplayed -> handleIsDisplayed()
|
||||
is RoomDetailActions.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailActions.EventDisplayed -> handleEventDisplayed(action)
|
||||
is RoomDetailActions.LoadMore -> handleLoadMore(action)
|
||||
is RoomDetailActions.LoadMore -> handleLoadMore(action)
|
||||
is RoomDetailActions.SendReaction -> handleSendReaction(action)
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,63 +89,63 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
val slashCommandResult = CommandParser.parseSplashCommand(action.text)
|
||||
|
||||
when (slashCommandResult) {
|
||||
is ParsedCommand.ErrorNotACommand -> {
|
||||
is ParsedCommand.ErrorNotACommand -> {
|
||||
// Send the text message to the room
|
||||
room.sendTextMessage(action.text)
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
||||
}
|
||||
is ParsedCommand.ErrorSyntax -> {
|
||||
is ParsedCommand.ErrorSyntax -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command)))
|
||||
}
|
||||
is ParsedCommand.ErrorEmptySlashCommand -> {
|
||||
is ParsedCommand.ErrorEmptySlashCommand -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown("/")))
|
||||
}
|
||||
is ParsedCommand.ErrorUnknownSlashCommand -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand)))
|
||||
}
|
||||
is ParsedCommand.Invite -> {
|
||||
is ParsedCommand.Invite -> {
|
||||
handleInviteSlashCommand(slashCommandResult)
|
||||
}
|
||||
is ParsedCommand.SetUserPowerLevel -> {
|
||||
is ParsedCommand.SetUserPowerLevel -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.ClearScalarToken -> {
|
||||
is ParsedCommand.ClearScalarToken -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.SetMarkdown -> {
|
||||
is ParsedCommand.SetMarkdown -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.UnbanUser -> {
|
||||
is ParsedCommand.UnbanUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.BanUser -> {
|
||||
is ParsedCommand.BanUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.KickUser -> {
|
||||
is ParsedCommand.KickUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.JoinRoom -> {
|
||||
is ParsedCommand.JoinRoom -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.PartRoom -> {
|
||||
is ParsedCommand.PartRoom -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.SendEmote -> {
|
||||
is ParsedCommand.SendEmote -> {
|
||||
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
|
||||
}
|
||||
is ParsedCommand.ChangeTopic -> {
|
||||
is ParsedCommand.ChangeTopic -> {
|
||||
handleChangeTopicSlashCommand(slashCommandResult)
|
||||
}
|
||||
is ParsedCommand.ChangeDisplayName -> {
|
||||
is ParsedCommand.ChangeDisplayName -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
@ -179,6 +180,11 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private fun handleSendReaction(action: RoomDetailActions.SendReaction) {
|
||||
room.sendReaction(action.reaction,action.targetEventId)
|
||||
}
|
||||
|
||||
private fun handleSendMedia(action: RoomDetailActions.SendMedia) {
|
||||
val attachments = action.mediaFiles.map {
|
||||
ContentAttachmentData(
|
||||
|
@ -95,8 +95,13 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
|
||||
.commit()
|
||||
}
|
||||
quickReactionFragment.interactionListener = object : QuickReactionFragment.InteractionListener {
|
||||
override fun didQuickReactWith(reactions: List<String>) {
|
||||
actionHandlerModel.fireAction("Quick React", reactions)
|
||||
override fun didQuickReactWith(clikedOn: String, reactions: List<String>, eventId: String) {
|
||||
if (reactions.contains(clikedOn)) {
|
||||
//it's an add
|
||||
actionHandlerModel.fireAction(MessageMenuViewModel.ACTION_QUICK_REACT, Pair(eventId,clikedOn))
|
||||
} else {
|
||||
//it's a remove
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
||||
|
||||
//TODO determine if can copy, forward, reply, quote, report?
|
||||
val actions = ArrayList<SimpleAction>().apply {
|
||||
this.add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_smile))
|
||||
this.add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_smile, event.root.eventId))
|
||||
if (canCopy(type)) {
|
||||
//TODO copy images? html? see ClipBoard
|
||||
this.add(SimpleAction(ACTION_COPY, R.string.copy, R.drawable.ic_copy, messageContent.body))
|
||||
@ -184,6 +184,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
||||
const val VIEW_DECRYPTED_SOURCE = "VIEW_DECRYPTED_SOURCE"
|
||||
const val PERMALINK = "PERMALINK"
|
||||
const val ACTION_FLAG = "ACTION_FLAG"
|
||||
const val ACTION_QUICK_REACT = "ACTION_QUICK_REACT"
|
||||
|
||||
|
||||
}
|
||||
|
@ -119,12 +119,12 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
||||
}
|
||||
|
||||
if (it.selectionResult != null) {
|
||||
interactionListener?.didQuickReactWith(it.selectionResult)
|
||||
interactionListener?.didQuickReactWith(it.selectionResult.first, it.selectionResult.second, it.eventId)
|
||||
}
|
||||
}
|
||||
|
||||
interface InteractionListener {
|
||||
fun didQuickReactWith(reactions: List<String>)
|
||||
fun didQuickReactWith(clikedOn: String, reactions: List<String>, eventId: String)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -31,7 +31,12 @@ enum class TriggleState {
|
||||
SECOND
|
||||
}
|
||||
|
||||
data class QuickReactionState(val agreeTrigleState: TriggleState, val likeTriggleState: TriggleState, val selectionResult: List<String>? = null) : MvRxState
|
||||
data class QuickReactionState(
|
||||
val agreeTrigleState: TriggleState,
|
||||
val likeTriggleState: TriggleState,
|
||||
/** Pair of 'clickedOn' and current toggles state*/
|
||||
val selectionResult: Pair<String, List<String>>? = null,
|
||||
val eventId: String) : MvRxState
|
||||
|
||||
/**
|
||||
* Quick reaction view model
|
||||
@ -43,16 +48,18 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
||||
fun toggleAgree(isFirst: Boolean) = withState {
|
||||
if (isFirst) {
|
||||
setState {
|
||||
val newTriggle = if (it.agreeTrigleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
||||
copy(
|
||||
agreeTrigleState = if (it.agreeTrigleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST,
|
||||
selectionResult = getReactions(this)
|
||||
agreeTrigleState = newTriggle,
|
||||
selectionResult = Pair(agreePositive, getReactions(this, newTriggle, null))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
setState {
|
||||
val newTriggle = if (it.agreeTrigleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
||||
copy(
|
||||
agreeTrigleState = if (it.agreeTrigleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND,
|
||||
selectionResult = getReactions(this)
|
||||
agreeTrigleState = agreeTrigleState,
|
||||
selectionResult = Pair(agreeNegative, getReactions(this, newTriggle, null))
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -61,30 +68,32 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
||||
fun toggleLike(isFirst: Boolean) = withState {
|
||||
if (isFirst) {
|
||||
setState {
|
||||
val newTriggle = if (it.likeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
||||
copy(
|
||||
likeTriggleState = if (it.likeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST,
|
||||
selectionResult = getReactions(this)
|
||||
likeTriggleState = newTriggle,
|
||||
selectionResult = Pair(likePositive, getReactions(this, null, newTriggle))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
setState {
|
||||
val newTriggle = if (it.likeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
||||
copy(
|
||||
likeTriggleState = if (it.likeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND,
|
||||
selectionResult = getReactions(this)
|
||||
likeTriggleState = newTriggle,
|
||||
selectionResult = Pair(likeNegative, getReactions(this, null, newTriggle))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getReactions(state: QuickReactionState): List<String> {
|
||||
private fun getReactions(state: QuickReactionState, newState1: TriggleState?, newState2: TriggleState?): List<String> {
|
||||
return ArrayList<String>(4).apply {
|
||||
when (state.likeTriggleState) {
|
||||
when (newState2 ?: state.likeTriggleState) {
|
||||
TriggleState.FIRST -> add(likePositive)
|
||||
TriggleState.SECOND -> add(likeNegative)
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
when (state.agreeTrigleState) {
|
||||
when (newState1 ?: state.agreeTrigleState) {
|
||||
TriggleState.FIRST -> add(agreePositive)
|
||||
TriggleState.SECOND -> add(agreeNegative)
|
||||
else -> {
|
||||
@ -126,7 +135,7 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
return QuickReactionState(agreeTriggle, likeTriggle)
|
||||
return QuickReactionState(agreeTriggle, likeTriggle, null, event.root.eventId ?: "")
|
||||
}
|
||||
}
|
||||
}
|
@ -88,8 +88,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
//clear all reaction buttons (but not the Flow helper!)
|
||||
holder.reactionWrapper?.children?.forEach { (it as? ReactionButton)?.isGone = true }
|
||||
val idToRefInFlow = ArrayList<Int>()
|
||||
informationData.orderedReactionList?.forEachIndexed { index, reaction ->
|
||||
(holder.reactionWrapper?.children?.elementAt(index) as? ReactionButton)?.let { reactionButton ->
|
||||
informationData.orderedReactionList?.chunked(7)?.firstOrNull()?.forEachIndexed { index, reaction ->
|
||||
(holder.reactionWrapper?.children?.elementAtOrNull(index) as? ReactionButton)?.let { reactionButton ->
|
||||
reactionButton.isVisible = true
|
||||
idToRefInFlow.add(reactionButton.id)
|
||||
reactionButton.reactionString = reaction.first
|
||||
|
@ -18,22 +18,34 @@ package im.vector.riotredesign.features.reactions
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import im.vector.riotredesign.core.utils.LiveEvent
|
||||
|
||||
class EmojiChooserViewModel : ViewModel() {
|
||||
|
||||
var adapter: EmojiRecyclerAdapter? = null
|
||||
val emojiSourceLiveData: MutableLiveData<EmojiDataSource> = MutableLiveData()
|
||||
|
||||
val navigateEvent: MutableLiveData<LiveEvent<String>> = MutableLiveData()
|
||||
var selectedReaction: String? = null
|
||||
var eventId: String? = null
|
||||
|
||||
val currentSection: MutableLiveData<Int> = MutableLiveData()
|
||||
|
||||
var reactionClickListener = object : ReactionClickListener {
|
||||
override fun onReactionSelected(reaction: String) {
|
||||
selectedReaction = reaction
|
||||
navigateEvent.value = LiveEvent(NAVIGATE_FINISH)
|
||||
}
|
||||
}
|
||||
|
||||
fun initWithContect(context: Context) {
|
||||
//TODO load async
|
||||
val emojiDataSource = EmojiDataSource(context)
|
||||
emojiSourceLiveData.value = emojiDataSource
|
||||
adapter = EmojiRecyclerAdapter(emojiDataSource)
|
||||
adapter = EmojiRecyclerAdapter(emojiDataSource, reactionClickListener)
|
||||
adapter?.interactionListener = object : EmojiRecyclerAdapter.InteractionListener {
|
||||
override fun firstVisibleSectionChange(section: Int) {
|
||||
currentSection.value = section
|
||||
currentSection.value = section
|
||||
}
|
||||
|
||||
}
|
||||
@ -42,4 +54,8 @@ class EmojiChooserViewModel : ViewModel() {
|
||||
fun scrollToSection(sectionIndex: Int) {
|
||||
adapter?.scrollToSection(sectionIndex)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NAVIGATE_FINISH = "NAVIGATE_FINISH"
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package im.vector.riotredesign.features.reactions
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
@ -88,6 +89,8 @@ class EmojiReactionPickerActivity : VectorBaseActivity() {
|
||||
|
||||
viewModel = ViewModelProviders.of(this).get(EmojiChooserViewModel::class.java)
|
||||
|
||||
viewModel.eventId = intent.getStringExtra(EXTRA_EVENT_ID)
|
||||
|
||||
viewModel.emojiSourceLiveData.observe(this, Observer {
|
||||
it.rawData?.categories?.let { categories ->
|
||||
for (category in categories) {
|
||||
@ -106,6 +109,19 @@ class EmojiReactionPickerActivity : VectorBaseActivity() {
|
||||
tabLayout.addOnTabSelectedListener(tabLayoutSelectionListener)
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.navigateEvent.observe(this, Observer {
|
||||
it.getContentIfNotHandled()?.let {
|
||||
if (it == EmojiChooserViewModel.NAVIGATE_FINISH) {
|
||||
//finish with result
|
||||
val dataResult = Intent()
|
||||
dataResult.putExtra(EXTRA_REACTION_RESULT, viewModel.selectedReaction)
|
||||
dataResult.putExtra(EXTRA_EVENT_ID, viewModel.eventId)
|
||||
setResult(Activity.RESULT_OK, dataResult)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun requestEmojivUnicode10CompatibleFont() {
|
||||
@ -172,9 +188,13 @@ class EmojiReactionPickerActivity : VectorBaseActivity() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun intent(context: Context): Intent {
|
||||
|
||||
const val EXTRA_EVENT_ID = "EXTRA_EVENT_ID"
|
||||
const val EXTRA_REACTION_RESULT = "EXTRA_REACTION_RESULT"
|
||||
|
||||
fun intent(context: Context, eventId: String): Intent {
|
||||
val intent = Intent(context, EmojiReactionPickerActivity::class.java)
|
||||
// intent.putExtra(EXTRA_MATRIX_ID, matrixID)
|
||||
intent.putExtra(EXTRA_EVENT_ID, eventId)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import kotlin.math.abs
|
||||
* TODO: Performances
|
||||
* TODO: Scroll to section - Find a way to snap section to the top
|
||||
*/
|
||||
class EmojiRecyclerAdapter(val dataSource: EmojiDataSource? = null) :
|
||||
class EmojiRecyclerAdapter(val dataSource: EmojiDataSource? = null, var reactionClickListener: ReactionClickListener?) :
|
||||
RecyclerView.Adapter<EmojiRecyclerAdapter.ViewHolder>() {
|
||||
|
||||
var interactionListener: InteractionListener? = null
|
||||
@ -64,6 +64,22 @@ class EmojiRecyclerAdapter(val dataSource: EmojiDataSource? = null) :
|
||||
|
||||
val toUpdateWhenNotBusy = ArrayList<Pair<String, EmojiViewHolder>>()
|
||||
|
||||
val itemClickListener = View.OnClickListener { view ->
|
||||
mRecyclerView?.getChildLayoutPosition(view)?.let { itemPosition ->
|
||||
if (itemPosition != RecyclerView.NO_POSITION) {
|
||||
val categories = dataSource?.rawData?.categories ?: return@OnClickListener
|
||||
val sectionNumber = getSectionForAbsoluteIndex(itemPosition)
|
||||
if (!isSection(itemPosition)) {
|
||||
val sectionMojis = categories[sectionNumber].emojis
|
||||
val sectionOffset = getSectionOffset(sectionNumber)
|
||||
val emoji = sectionMojis[itemPosition - sectionOffset]
|
||||
val item = dataSource.rawData!!.emojis.getValue(emoji).emojiString()
|
||||
reactionClickListener?.onReactionSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||
super.onAttachedToRecyclerView(recyclerView)
|
||||
@ -113,6 +129,7 @@ class EmojiRecyclerAdapter(val dataSource: EmojiDataSource? = null) :
|
||||
beginTraceSession("MyAdapter.onCreateViewHolder")
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val itemView = inflater.inflate(viewType, parent, false)
|
||||
itemView.setOnClickListener(itemClickListener)
|
||||
val viewHolder = when (viewType) {
|
||||
R.layout.grid_section_header -> SectionViewHolder(itemView)
|
||||
else -> EmojiViewHolder(itemView)
|
||||
|
@ -0,0 +1,5 @@
|
||||
package im.vector.riotredesign.features.reactions
|
||||
|
||||
interface ReactionClickListener {
|
||||
fun onReactionSelected(reaction: String)
|
||||
}
|
Reference in New Issue
Block a user