Merge pull request #3435 from vector-im/feature/bma/debounced_click

Debounced click
This commit is contained in:
Benoit Marty 2021-06-08 19:12:03 +02:00 committed by GitHub
commit d4f48da7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
152 changed files with 718 additions and 804 deletions

View File

@ -0,0 +1 @@
Cleanup Epoxy items, and debounce all the clicks

View File

@ -29,14 +29,14 @@ abstract class ErrorWithRetryItem : VectorEpoxyModel<ErrorWithRetryItem.Holder>(
@EpoxyAttribute @EpoxyAttribute
var text: String? = null var text: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var listener: (() -> Unit)? = null var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.textView.text = text holder.textView.text = text
holder.buttonView.isVisible = listener != null holder.buttonView.isVisible = listener != null
holder.buttonView.setOnClickListener { listener?.invoke() } holder.buttonView.onClick(listener)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -17,12 +17,22 @@
package im.vector.app.core.epoxy package im.vector.app.core.epoxy
import android.view.View import android.view.View
import im.vector.app.core.utils.DebouncedClickListener
/** /**
* Generally we do not care about the View parameter in [View.OnClickListener.onClick()], so create facility to remove it. * View.OnClickListener lambda
*/ */
typealias ClickListener = () -> Unit typealias ClickListener = (View) -> Unit
fun View.onClick(listener: ClickListener?) { fun View.onClick(listener: ClickListener?) {
setOnClickListener { listener?.invoke() } if (listener == null) {
setOnClickListener(null)
} else {
setOnClickListener(DebouncedClickListener(listener))
} }
}
/**
* Simple Text listener lambda
*/
typealias TextListener = (String) -> Unit

View File

@ -16,7 +16,9 @@
package im.vector.app.core.epoxy package im.vector.app.core.epoxy
import android.text.TextWatcher
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.TextView
import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
@ -39,3 +41,9 @@ fun VectorEpoxyHolder.setValueOnce(switchView: SwitchMaterial, switchChecked: Bo
switchView.setOnCheckedChangeListener(listener) switchView.setOnCheckedChangeListener(listener)
} }
} }
fun TextView.addTextChangedListenerOnce(textWatcher: TextWatcher) {
// Ensure the watcher is not added multiple times
removeTextChangedListener(textWatcher)
addTextChangedListener(textWatcher)
}

View File

@ -30,8 +30,10 @@ import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
/** /**
@ -69,14 +71,12 @@ abstract class BottomSheetActionItem : VectorEpoxyModel<BottomSheetActionItem.Ho
@EpoxyAttribute @EpoxyAttribute
var destructive = false var destructive = false
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var listener: View.OnClickListener lateinit var listener: ClickListener
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.view.setOnClickListener { holder.view.onClick(listener)
listener.onClick(it)
}
holder.startSpace.isVisible = subMenuItem holder.startSpace.isVisible = subMenuItem
val tintColor = if (destructive) { val tintColor = if (destructive) {
ContextCompat.getColor(holder.view.context, R.color.riotx_notice) ContextCompat.getColor(holder.view.context, R.color.riotx_notice)

View File

@ -23,8 +23,10 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
@ -61,14 +63,14 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
@EpoxyAttribute @EpoxyAttribute
var movementMethod: MovementMethod? = null var movementMethod: MovementMethod? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var userClicked: (() -> Unit)? = null var userClicked: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
avatarRenderer.render(matrixItem, holder.avatar) avatarRenderer.render(matrixItem, holder.avatar)
holder.avatar.setOnClickListener { userClicked?.invoke() } holder.avatar.onClick(userClicked)
holder.sender.setOnClickListener { userClicked?.invoke() } holder.sender.onClick(userClicked)
holder.sender.setTextOrHide(matrixItem.displayName) holder.sender.setTextOrHide(matrixItem.displayName)
data?.let { data?.let {
imageContentRenderer?.render(it, ImageContentRenderer.Mode.THUMBNAIL, holder.imagePreview) imageContentRenderer?.render(it, ImageContentRenderer.Mode.THUMBNAIL, holder.imagePreview)

View File

@ -24,6 +24,7 @@ import im.vector.app.EmojiCompatFontProvider
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
/** /**
* A quick reaction list for bottom sheet. * A quick reaction list for bottom sheet.
@ -50,7 +51,7 @@ abstract class BottomSheetQuickReactionsItem : VectorEpoxyModel<BottomSheetQuick
textView.text = texts[index] textView.text = texts[index]
textView.alpha = if (selecteds[index]) 0.2f else 1f textView.alpha = if (selecteds[index]) 0.2f else 1f
textView.setOnClickListener { textView.onClick {
listener?.didSelect(texts[index], !selecteds[index]) listener?.didSelect(texts[index], !selecteds[index])
} }
} }

View File

@ -16,7 +16,6 @@
*/ */
package im.vector.app.core.epoxy.bottomsheet package im.vector.app.core.epoxy.bottomsheet
import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
@ -24,8 +23,10 @@ import androidx.core.content.ContextCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
/** /**
@ -47,15 +48,12 @@ abstract class BottomSheetRadioActionItem : VectorEpoxyModel<BottomSheetRadioAct
@EpoxyAttribute @EpoxyAttribute
var description: CharSequence? = null var description: CharSequence? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var listener: View.OnClickListener lateinit var listener: ClickListener
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.view.setOnClickListener { holder.view.onClick(listener)
listener.onClick(it)
}
if (titleRes != null) { if (titleRes != null) {
holder.titleText.setText(titleRes!!) holder.titleText.setText(titleRes!!)
} else { } else {

View File

@ -47,9 +47,9 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
@EpoxyAttribute lateinit var stringProvider: StringProvider @EpoxyAttribute lateinit var stringProvider: StringProvider
@EpoxyAttribute var izLowPriority: Boolean = false @EpoxyAttribute var izLowPriority: Boolean = false
@EpoxyAttribute var izFavorite: Boolean = false @EpoxyAttribute var izFavorite: Boolean = false
@EpoxyAttribute var settingsClickListener: ClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var settingsClickListener: ClickListener? = null
@EpoxyAttribute var lowPriorityClickListener: ClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var lowPriorityClickListener: ClickListener? = null
@EpoxyAttribute var favoriteClickListener: ClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var favoriteClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -59,7 +59,7 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
setLowPriorityState(holder, izLowPriority) setLowPriorityState(holder, izLowPriority)
setFavoriteState(holder, izFavorite) setFavoriteState(holder, izFavorite)
holder.roomLowPriority.setOnClickListener { holder.roomLowPriority.onClick {
// Immediate echo // Immediate echo
setLowPriorityState(holder, !izLowPriority) setLowPriorityState(holder, !izLowPriority)
if (!izLowPriority) { if (!izLowPriority) {
@ -67,9 +67,9 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
setFavoriteState(holder, false) setFavoriteState(holder, false)
} }
// And do the action // And do the action
lowPriorityClickListener?.invoke() lowPriorityClickListener?.invoke(it)
} }
holder.roomFavorite.setOnClickListener { holder.roomFavorite.onClick {
// Immediate echo // Immediate echo
setFavoriteState(holder, !izFavorite) setFavoriteState(holder, !izFavorite)
if (!izFavorite) { if (!izFavorite) {
@ -77,7 +77,7 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
setLowPriorityState(holder, false) setLowPriorityState(holder, false)
} }
// And do the action // And do the action
favoriteClickListener?.invoke() favoriteClickListener?.invoke(it)
} }
holder.roomSettings.apply { holder.roomSettings.apply {
onClick(settingsClickListener) onClick(settingsClickListener)

View File

@ -16,11 +16,12 @@
package im.vector.app.core.epoxy.profiles package im.vector.app.core.epoxy.profiles
import android.view.View
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
@ -33,7 +34,9 @@ abstract class BaseProfileMatrixItem<T : ProfileMatrixItem.Holder> : VectorEpoxy
@EpoxyAttribute @EpoxyAttribute
var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
@EpoxyAttribute var clickListener: View.OnClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: ClickListener? = null
@CallSuper @CallSuper
override fun bind(holder: T) { override fun bind(holder: T) {
@ -43,7 +46,7 @@ abstract class BaseProfileMatrixItem<T : ProfileMatrixItem.Holder> : VectorEpoxy
.takeIf { it != bestName } .takeIf { it != bestName }
// Special case for ThreePid fake matrix item // Special case for ThreePid fake matrix item
.takeIf { it != "@" } .takeIf { it != "@" }
holder.view.setOnClickListener(clickListener?.takeIf { editable }) holder.view.onClick(clickListener?.takeIf { editable })
holder.titleView.text = bestName holder.titleView.text = bestName
holder.subtitleView.setTextOrHide(matrixId) holder.subtitleView.setTextOrHide(matrixId)
holder.editableView.isVisible = editable holder.editableView.isVisible = editable

View File

@ -67,7 +67,7 @@ abstract class ProfileActionItem : VectorEpoxyModel<ProfileActionItem.Holder>()
@EpoxyAttribute @EpoxyAttribute
var destructive: Boolean = false var destructive: Boolean = false
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var listener: ClickListener? = null var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -24,6 +24,8 @@ import android.widget.FrameLayout
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.databinding.ViewButtonStateBinding import im.vector.app.databinding.ViewButtonStateBinding
class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
@ -36,12 +38,9 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
object Error : State() object Error : State()
} }
var callback: Callback? = null var commonClicked: ClickListener? = null
var buttonClicked: ClickListener? = null
interface Callback { var retryClicked: ClickListener? = null
fun onButtonClicked()
fun onRetryClicked()
}
// Big or Flat button // Big or Flat button
var button: Button var button: Button
@ -54,8 +53,9 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
layoutParams = LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) layoutParams = LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
views.buttonStateRetry.setOnClickListener { views.buttonStateRetry.onClick {
callback?.onRetryClicked() commonClicked?.invoke(it)
retryClicked?.invoke(it)
} }
// Read attributes // Read attributes
@ -80,8 +80,9 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
} }
} }
button.setOnClickListener { button.onClick {
callback?.onButtonClicked() commonClicked?.invoke(it)
buttonClicked?.invoke(it)
} }
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.core.ui.bottomsheet package im.vector.app.core.ui.bottomsheet
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
/** /**
@ -51,7 +50,7 @@ abstract class BottomSheetGenericController<State : BottomSheetGenericState, Act
val actions = getActions(state) val actions = getActions(state)
actions.forEach { action -> actions.forEach { action ->
action.toRadioBottomSheetItem() action.toRadioBottomSheetItem()
.listener(View.OnClickListener { listener?.didSelectAction(action) }) .listener { listener?.didSelectAction(action) }
.addTo(this) .addTo(this)
} }
} }

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.list
import im.vector.app.core.epoxy.ClickListener
data class Action(
val title: String,
val listener: ClickListener
)

View File

@ -15,15 +15,16 @@
*/ */
package im.vector.app.core.ui.list package im.vector.app.core.ui.list
import android.view.View
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
/** /**
@ -35,8 +36,8 @@ abstract class GenericButtonItem : VectorEpoxyModel<GenericButtonItem.Holder>()
@EpoxyAttribute @EpoxyAttribute
var text: String? = null var text: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var buttonClickAction: View.OnClickListener? = null var buttonClickAction: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
@ColorInt @ColorInt
@ -57,7 +58,7 @@ abstract class GenericButtonItem : VectorEpoxyModel<GenericButtonItem.Holder>()
holder.button.icon = null holder.button.icon = null
} }
buttonClickAction?.let { holder.button.setOnClickListener(it) } holder.button.onClick(buttonClickAction)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -29,6 +29,7 @@ import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
/** /**
@ -37,10 +38,6 @@ import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_generic_empty_state) @EpoxyModelClass(layout = R.layout.item_generic_empty_state)
abstract class GenericEmptyWithActionItem : VectorEpoxyModel<GenericEmptyWithActionItem.Holder>() { abstract class GenericEmptyWithActionItem : VectorEpoxyModel<GenericEmptyWithActionItem.Holder>() {
class Action(var title: String) {
var perform: Runnable? = null
}
@EpoxyAttribute @EpoxyAttribute
var title: CharSequence? = null var title: CharSequence? = null
@ -77,9 +74,7 @@ abstract class GenericEmptyWithActionItem : VectorEpoxyModel<GenericEmptyWithAct
} }
holder.actionButton.setTextOrHide(buttonAction?.title) holder.actionButton.setTextOrHide(buttonAction?.title)
holder.actionButton.setOnClickListener { holder.actionButton.onClick(buttonAction?.listener)
buttonAction?.perform?.run()
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -21,8 +21,10 @@ import androidx.annotation.ColorInt
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -41,8 +43,8 @@ abstract class GenericFooterItem : VectorEpoxyModel<GenericFooterItem.Holder>()
@EpoxyAttribute @EpoxyAttribute
var style: ItemStyle = ItemStyle.NORMAL_TEXT var style: ItemStyle = ItemStyle.NORMAL_TEXT
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickAction: GenericItem.Action? = null var itemClickAction: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var centered: Boolean = true var centered: Boolean = true
@ -65,9 +67,7 @@ abstract class GenericFooterItem : VectorEpoxyModel<GenericFooterItem.Holder>()
holder.text.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)) holder.text.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary))
} }
holder.view.setOnClickListener { holder.view.onClick(itemClickAction)
itemClickAction?.perform?.run()
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -29,7 +29,7 @@ import im.vector.app.features.themes.ThemeUtils
* A generic list item header left aligned with notice color. * A generic list item header left aligned with notice color.
*/ */
@EpoxyModelClass(layout = R.layout.item_generic_header) @EpoxyModelClass(layout = R.layout.item_generic_header)
abstract class GenericItemHeader : VectorEpoxyModel<GenericItemHeader.Holder>() { abstract class GenericHeaderItem : VectorEpoxyModel<GenericHeaderItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var text: String? = null var text: String? = null

View File

@ -25,8 +25,10 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
/** /**
@ -38,10 +40,6 @@ import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_generic_list) @EpoxyModelClass(layout = R.layout.item_generic_list)
abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() { abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
class Action(var title: String) {
var perform: Runnable? = null
}
@EpoxyAttribute @EpoxyAttribute
var title: CharSequence? = null var title: CharSequence? = null
@ -68,8 +66,8 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var destructiveButtonAction: Action? = null var destructiveButtonAction: Action? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickAction: Action? = null var itemClickAction: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -100,18 +98,12 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
} }
holder.actionButton.setTextOrHide(buttonAction?.title) holder.actionButton.setTextOrHide(buttonAction?.title)
holder.actionButton.setOnClickListener { holder.actionButton.onClick(buttonAction?.listener)
buttonAction?.perform?.run()
}
holder.destructiveButton.setTextOrHide(destructiveButtonAction?.title) holder.destructiveButton.setTextOrHide(destructiveButtonAction?.title)
holder.destructiveButton.setOnClickListener { holder.destructiveButton.onClick(destructiveButtonAction?.listener)
destructiveButtonAction?.perform?.run()
}
holder.root.setOnClickListener { holder.root.onClick(itemClickAction)
itemClickAction?.perform?.run()
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -25,8 +25,10 @@ import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -42,8 +44,8 @@ abstract class GenericPillItem : VectorEpoxyModel<GenericPillItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var style: ItemStyle = ItemStyle.NORMAL_TEXT var style: ItemStyle = ItemStyle.NORMAL_TEXT
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickAction: GenericItem.Action? = null var itemClickAction: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var centered: Boolean = false var centered: Boolean = false
@ -76,9 +78,7 @@ abstract class GenericPillItem : VectorEpoxyModel<GenericPillItem.Holder>() {
ImageViewCompat.setImageTintList(holder.imageView, null) ImageViewCompat.setImageTintList(holder.imageView, null)
} }
holder.view.setOnClickListener { holder.view.onClick(itemClickAction)
itemClickAction?.perform?.run()
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -15,15 +15,16 @@
*/ */
package im.vector.app.core.ui.list package im.vector.app.core.ui.list
import android.view.View
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
/** /**
* A generic button list item. * A generic button list item.
@ -34,8 +35,8 @@ abstract class GenericPositiveButtonItem : VectorEpoxyModel<GenericPositiveButto
@EpoxyAttribute @EpoxyAttribute
var text: String? = null var text: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var buttonClickAction: View.OnClickListener? = null var buttonClickAction: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
@ColorInt @ColorInt
@ -53,8 +54,7 @@ abstract class GenericPositiveButtonItem : VectorEpoxyModel<GenericPositiveButto
} else { } else {
holder.button.icon = null holder.button.icon = null
} }
holder.button.onClick(buttonClickAction)
buttonClickAction?.let { holder.button.setOnClickListener(it) }
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -24,10 +24,11 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
/** /**
@ -37,7 +38,7 @@ import im.vector.app.features.themes.ThemeUtils
* If provided with an action, will display a button at the bottom of the list item. * If provided with an action, will display a button at the bottom of the list item.
*/ */
@EpoxyModelClass(layout = R.layout.item_generic_with_value) @EpoxyModelClass(layout = R.layout.item_generic_with_value)
abstract class GenericItemWithValue : VectorEpoxyModel<GenericItemWithValue.Holder>() { abstract class GenericWithValueItem : VectorEpoxyModel<GenericWithValueItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var title: CharSequence? = null var title: CharSequence? = null
@ -53,10 +54,10 @@ abstract class GenericItemWithValue : VectorEpoxyModel<GenericItemWithValue.Hold
@DrawableRes @DrawableRes
var titleIconResourceId: Int = -1 var titleIconResourceId: Int = -1
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickAction: View.OnClickListener? = null var itemClickAction: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemLongClickAction: View.OnLongClickListener? = null var itemLongClickAction: View.OnLongClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
@ -78,7 +79,7 @@ abstract class GenericItemWithValue : VectorEpoxyModel<GenericItemWithValue.Hold
holder.valueText.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary)) holder.valueText.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary))
} }
holder.view.setOnClickListener(itemClickAction?.let { DebouncedClickListener(it) }) holder.view.onClick(itemClickAction)
holder.view.setOnLongClickListener(itemLongClickAction) holder.view.setOnLongClickListener(itemLongClickAction)
} }

View File

@ -18,10 +18,10 @@ package im.vector.app.core.ui.views
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import im.vector.app.core.utils.DebouncedClickListener import im.vector.app.core.epoxy.onClick
import org.matrix.android.sdk.api.session.call.CallState
import im.vector.app.features.call.utils.EglUtils import im.vector.app.features.call.utils.EglUtils
import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCall
import org.matrix.android.sdk.api.session.call.CallState
import org.webrtc.RendererCommon import org.webrtc.RendererCommon
import org.webrtc.SurfaceViewRenderer import org.webrtc.SurfaceViewRenderer
@ -88,11 +88,9 @@ class KnownCallsViewHolder {
this.currentCallsView = activeCallView this.currentCallsView = activeCallView
this.pipWrapper = pipWrapper this.pipWrapper = pipWrapper
this.currentCallsView?.callback = interactionListener this.currentCallsView?.callback = interactionListener
pipWrapper.setOnClickListener( pipWrapper.onClick {
DebouncedClickListener({
interactionListener.onTapToReturnToCall() interactionListener.onTapToReturnToCall()
}) }
)
this.currentCall?.addListener(tickListener) this.currentCall?.addListener(tickListener)
} }

View File

@ -59,8 +59,7 @@ class ReadReceiptsView @JvmOverloads constructor(
contentDescription = context.getString(R.string.a11y_view_read_receipts) contentDescription = context.getString(R.string.a11y_view_read_receipts)
} }
fun render(readReceipts: List<ReadReceiptData>, avatarRenderer: AvatarRenderer, clickListener: OnClickListener) { fun render(readReceipts: List<ReadReceiptData>, avatarRenderer: AvatarRenderer) {
setOnClickListener(clickListener)
if (readReceipts.isNotEmpty()) { if (readReceipts.isNotEmpty()) {
isVisible = true isVisible = true
for (index in 0 until MAX_RECEIPT_DISPLAYED) { for (index in 0 until MAX_RECEIPT_DISPLAYED) {

View File

@ -15,24 +15,30 @@
*/ */
package im.vector.app.core.utils package im.vector.app.core.utils
import android.os.SystemClock
import android.view.View import android.view.View
import timber.log.Timber
import java.util.WeakHashMap import java.util.WeakHashMap
/** /**
* Simple Debounced OnClickListener * Simple Debounced OnClickListener
* Safe to use in different views * Safe to use in different views
*/ */
class DebouncedClickListener(val original: View.OnClickListener, private val minimumInterval: Long = 400) : View.OnClickListener { class DebouncedClickListener(
val original: View.OnClickListener,
private val minimumInterval: Long = 400
) : View.OnClickListener {
private val lastClickMap = WeakHashMap<View, Long>() private val lastClickMap = WeakHashMap<View, Long>()
override fun onClick(clickedView: View) { override fun onClick(v: View) {
val previousClickTimestamp = lastClickMap[clickedView] val previousClickTimestamp = lastClickMap[v] ?: 0
val currentTimestamp = System.currentTimeMillis() val currentTimestamp = SystemClock.elapsedRealtime()
lastClickMap[v] = currentTimestamp
lastClickMap[clickedView] = currentTimestamp if (currentTimestamp > previousClickTimestamp + minimumInterval) {
original.onClick(v)
if (previousClickTimestamp == null || currentTimestamp - previousClickTimestamp.toLong() > minimumInterval) { } else {
original.onClick(clickedView) Timber.v("Debounced click!")
} }
} }
} }

View File

@ -16,14 +16,15 @@
package im.vector.app.features.autocomplete package im.vector.app.features.autocomplete
import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -34,11 +35,11 @@ abstract class AutocompleteMatrixItem : VectorEpoxyModel<AutocompleteMatrixItem.
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute lateinit var matrixItem: MatrixItem @EpoxyAttribute lateinit var matrixItem: MatrixItem
@EpoxyAttribute var subName: String? = null @EpoxyAttribute var subName: String? = null
@EpoxyAttribute var clickListener: View.OnClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var clickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.view.setOnClickListener(clickListener) holder.view.onClick(clickListener)
holder.nameView.text = matrixItem.getBestName() holder.nameView.text = matrixItem.getBestName()
holder.subNameView.setTextOrHide(subName) holder.subNameView.setTextOrHide(subName)
avatarRenderer.render(matrixItem, holder.avatarImageView) avatarRenderer.render(matrixItem, holder.avatarImageView)

View File

@ -37,9 +37,7 @@ class AutocompleteCommandController @Inject constructor(private val stringProvid
name(command.command) name(command.command)
parameters(command.parameters) parameters(command.parameters)
description(host.stringProvider.getString(command.description)) description(host.stringProvider.getString(command.description))
clickListener { _ -> clickListener { host.listener?.onItemClick(command) }
host.listener?.onItemClick(command)
}
} }
} }
} }

View File

@ -16,13 +16,14 @@
package im.vector.app.features.autocomplete.command package im.vector.app.features.autocomplete.command
import android.view.View
import android.widget.TextView import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
@EpoxyModelClass(layout = R.layout.item_autocomplete_command) @EpoxyModelClass(layout = R.layout.item_autocomplete_command)
abstract class AutocompleteCommandItem : VectorEpoxyModel<AutocompleteCommandItem.Holder>() { abstract class AutocompleteCommandItem : VectorEpoxyModel<AutocompleteCommandItem.Holder>() {
@ -36,13 +37,12 @@ abstract class AutocompleteCommandItem : VectorEpoxyModel<AutocompleteCommandIte
@EpoxyAttribute @EpoxyAttribute
var description: CharSequence? = null var description: CharSequence? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: View.OnClickListener? = null var clickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.view.setOnClickListener(clickListener) holder.view.onClick(clickListener)
holder.nameView.text = name holder.nameView.text = name
holder.parametersView.text = parameters holder.parametersView.text = parameters
holder.descriptionView.text = description holder.descriptionView.text = description

View File

@ -21,7 +21,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import im.vector.app.EmojiCompatFontProvider import im.vector.app.EmojiCompatFontProvider
import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.AutocompleteClickListener
import im.vector.app.features.reactions.ReactionClickListener
import im.vector.app.features.reactions.data.EmojiItem import im.vector.app.features.reactions.data.EmojiItem
import javax.inject.Inject import javax.inject.Inject
@ -51,13 +50,7 @@ class AutocompleteEmojiController @Inject constructor(
id(emojiItem.name) id(emojiItem.name)
emojiItem(emojiItem) emojiItem(emojiItem)
emojiTypeFace(host.emojiTypeface) emojiTypeFace(host.emojiTypeface)
onClickListener( onClickListener { host.listener?.onItemClick(emojiItem.emoji) }
object : ReactionClickListener {
override fun onReactionSelected(reaction: String) {
host.listener?.onItemClick(reaction)
}
}
)
} }
} }

View File

@ -21,10 +21,11 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.reactions.ReactionClickListener
import im.vector.app.features.reactions.data.EmojiItem import im.vector.app.features.reactions.data.EmojiItem
@EpoxyModelClass(layout = R.layout.item_autocomplete_emoji) @EpoxyModelClass(layout = R.layout.item_autocomplete_emoji)
@ -36,8 +37,8 @@ abstract class AutocompleteEmojiItem : VectorEpoxyModel<AutocompleteEmojiItem.Ho
@EpoxyAttribute @EpoxyAttribute
var emojiTypeFace: Typeface? = null var emojiTypeFace: Typeface? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onClickListener: ReactionClickListener? = null var onClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -45,10 +46,7 @@ abstract class AutocompleteEmojiItem : VectorEpoxyModel<AutocompleteEmojiItem.Ho
holder.emojiText.typeface = emojiTypeFace ?: Typeface.DEFAULT holder.emojiText.typeface = emojiTypeFace ?: Typeface.DEFAULT
holder.emojiNameText.text = emojiItem.name holder.emojiNameText.text = emojiItem.name
holder.emojiKeywordText.setTextOrHide(emojiItem.keywords.joinToString()) holder.emojiKeywordText.setTextOrHide(emojiItem.keywords.joinToString())
holder.view.onClick(onClickListener)
holder.view.setOnClickListener {
onClickListener?.onReactionSelected(emojiItem.emoji)
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -40,9 +40,7 @@ class AutocompleteGroupController @Inject constructor() : TypedEpoxyController<L
id(groupSummary.groupId) id(groupSummary.groupId)
matrixItem(groupSummary.toMatrixItem()) matrixItem(groupSummary.toMatrixItem())
avatarRenderer(host.avatarRenderer) avatarRenderer(host.avatarRenderer)
clickListener { _ -> clickListener { host.listener?.onItemClick(groupSummary) }
host.listener?.onItemClick(groupSummary)
}
} }
} }
} }

View File

@ -40,9 +40,7 @@ class AutocompleteMemberController @Inject constructor() : TypedEpoxyController<
id(user.userId) id(user.userId)
matrixItem(user.toMatrixItem()) matrixItem(user.toMatrixItem())
avatarRenderer(host.avatarRenderer) avatarRenderer(host.avatarRenderer)
clickListener { _ -> clickListener { host.listener?.onItemClick(user) }
host.listener?.onItemClick(user)
}
} }
} }
} }

View File

@ -39,9 +39,7 @@ class AutocompleteRoomController @Inject constructor(private val avatarRenderer:
matrixItem(roomSummary.toMatrixItem()) matrixItem(roomSummary.toMatrixItem())
subName(roomSummary.canonicalAlias) subName(roomSummary.canonicalAlias)
avatarRenderer(host.avatarRenderer) avatarRenderer(host.avatarRenderer)
clickListener { _ -> clickListener { host.listener?.onItemClick(roomSummary) }
host.listener?.onItemClick(roomSummary)
}
} }
} }
} }

View File

@ -31,7 +31,9 @@ abstract class ContactDetailItem : VectorEpoxyModel<ContactDetailItem.Holder>()
@EpoxyAttribute lateinit var threePid: String @EpoxyAttribute lateinit var threePid: String
@EpoxyAttribute var matrixId: String? = null @EpoxyAttribute var matrixId: String? = null
@EpoxyAttribute var clickListener: ClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)

View File

@ -95,35 +95,35 @@ class ContactsBookController @Inject constructor(
avatarRenderer(host.avatarRenderer) avatarRenderer(host.avatarRenderer)
} }
mappedContact.emails mappedContact.emails
.forEachIndexed { index, it -> .forEachIndexed { index, email ->
if (onlyBoundContacts && it.matrixId == null) return@forEachIndexed if (onlyBoundContacts && email.matrixId == null) return@forEachIndexed
contactDetailItem { contactDetailItem {
id("${mappedContact.id}-e-$index-${it.email}") id("${mappedContact.id}-e-$index-${email.email}")
threePid(it.email) threePid(email.email)
matrixId(it.matrixId) matrixId(email.matrixId)
clickListener { clickListener {
if (it.matrixId != null) { if (email.matrixId != null) {
host.callback?.onMatrixIdClick(it.matrixId) host.callback?.onMatrixIdClick(email.matrixId)
} else { } else {
host.callback?.onThreePidClick(ThreePid.Email(it.email)) host.callback?.onThreePidClick(ThreePid.Email(email.email))
} }
} }
} }
} }
mappedContact.msisdns mappedContact.msisdns
.forEachIndexed { index, it -> .forEachIndexed { index, msisdn ->
if (onlyBoundContacts && it.matrixId == null) return@forEachIndexed if (onlyBoundContacts && msisdn.matrixId == null) return@forEachIndexed
contactDetailItem { contactDetailItem {
id("${mappedContact.id}-m-$index-${it.phoneNumber}") id("${mappedContact.id}-m-$index-${msisdn.phoneNumber}")
threePid(it.phoneNumber) threePid(msisdn.phoneNumber)
matrixId(it.matrixId) matrixId(msisdn.matrixId)
clickListener { clickListener {
if (it.matrixId != null) { if (msisdn.matrixId != null) {
host.callback?.onMatrixIdClick(it.matrixId) host.callback?.onMatrixIdClick(msisdn.matrixId)
} else { } else {
host.callback?.onThreePidClick(ThreePid.Msisdn(it.phoneNumber)) host.callback?.onThreePidClick(ThreePid.Msisdn(msisdn.phoneNumber))
} }
} }
} }

View File

@ -16,14 +16,15 @@
package im.vector.app.features.crypto.keysbackup.settings package im.vector.app.features.crypto.keysbackup.settings
import android.view.View
import android.widget.Button import android.widget.Button
import android.widget.TextView import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_keys_backup_settings_button_footer) @EpoxyModelClass(layout = R.layout.item_keys_backup_settings_button_footer)
@ -32,22 +33,22 @@ abstract class KeysBackupSettingFooterItem : VectorEpoxyModel<KeysBackupSettingF
@EpoxyAttribute @EpoxyAttribute
var textButton1: String? = null var textButton1: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickOnButton1: View.OnClickListener? = null var clickOnButton1: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var textButton2: String? = null var textButton2: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickOnButton2: View.OnClickListener? = null var clickOnButton2: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.button1.setTextOrHide(textButton1) holder.button1.setTextOrHide(textButton1)
holder.button1.setOnClickListener(clickOnButton1) holder.button1.onClick(clickOnButton1)
holder.button2.setTextOrHide(textButton2) holder.button2.setTextOrHide(textButton2)
holder.button2.setOnClickListener(clickOnButton2) holder.button2.onClick(clickOnButton2)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.crypto.keysbackup.settings package im.vector.app.features.crypto.keysbackup.settings
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@ -166,13 +165,13 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
if (isBackupAlreadySetup) { if (isBackupAlreadySetup) {
textButton1(host.stringProvider.getString(R.string.keys_backup_settings_restore_backup_button)) textButton1(host.stringProvider.getString(R.string.keys_backup_settings_restore_backup_button))
clickOnButton1(View.OnClickListener { host.listener?.didSelectRestoreMessageRecovery() }) clickOnButton1 { host.listener?.didSelectRestoreMessageRecovery() }
textButton2(host.stringProvider.getString(R.string.keys_backup_settings_delete_backup_button)) textButton2(host.stringProvider.getString(R.string.keys_backup_settings_delete_backup_button))
clickOnButton2(View.OnClickListener { host.listener?.didSelectDeleteSetupMessageRecovery() }) clickOnButton2 { host.listener?.didSelectDeleteSetupMessageRecovery() }
} else { } else {
textButton1(host.stringProvider.getString(R.string.keys_backup_setup)) textButton1(host.stringProvider.getString(R.string.keys_backup_setup))
clickOnButton1(View.OnClickListener { host.listener?.didSelectSetupMessageRecovery() }) clickOnButton1 { host.listener?.didSelectSetupMessageRecovery() }
} }
} }
} }

View File

@ -25,8 +25,10 @@ import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
/** /**
@ -51,15 +53,12 @@ abstract class BottomSheetVerificationActionItem : VectorEpoxyModel<BottomSheetV
@EpoxyAttribute @EpoxyAttribute
var iconColor: Int = -1 var iconColor: Int = -1
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var listener: () -> Unit lateinit var listener: ClickListener
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.view.setOnClickListener { holder.view.onClick(listener)
listener.invoke()
}
holder.title.text = title holder.title.text = title
holder.title.setTextColor(titleColor) holder.title.setTextColor(titleColor)

View File

@ -16,7 +16,6 @@
package im.vector.app.features.devtools package im.vector.app.features.devtools
import android.view.View
import com.airbnb.epoxy.EpoxyController import com.airbnb.epoxy.EpoxyController
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
@ -38,23 +37,23 @@ class RoomDevToolRootController @Inject constructor(
genericButtonItem { genericButtonItem {
id("explore") id("explore")
text(host.stringProvider.getString(R.string.dev_tools_explore_room_state)) text(host.stringProvider.getString(R.string.dev_tools_explore_room_state))
buttonClickAction(View.OnClickListener { buttonClickAction {
host.interactionListener?.processAction(RoomDevToolAction.ExploreRoomState) host.interactionListener?.processAction(RoomDevToolAction.ExploreRoomState)
}) }
} }
genericButtonItem { genericButtonItem {
id("send") id("send")
text(host.stringProvider.getString(R.string.dev_tools_send_custom_event)) text(host.stringProvider.getString(R.string.dev_tools_send_custom_event))
buttonClickAction(View.OnClickListener { buttonClickAction {
host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false)) host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false))
}) }
} }
genericButtonItem { genericButtonItem {
id("send_state") id("send_state")
text(host.stringProvider.getString(R.string.dev_tools_send_state_event)) text(host.stringProvider.getString(R.string.dev_tools_send_state_event))
buttonClickAction(View.OnClickListener { buttonClickAction {
host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true)) host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true))
}) }
} }
} }
} }

View File

@ -21,7 +21,6 @@ import im.vector.app.R
import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.epoxy.noResultItem
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.GenericItem
import im.vector.app.core.ui.list.genericItem import im.vector.app.core.ui.list.genericItem
import me.gujun.android.span.span import me.gujun.android.span.span
import org.json.JSONObject import org.json.JSONObject
@ -51,11 +50,9 @@ class RoomStateListController @Inject constructor(
id(entry.key) id(entry.key)
title(entry.key) title(entry.key)
description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size)) description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size))
itemClickAction(GenericItem.Action("view").apply { itemClickAction {
perform = Runnable {
host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key)) host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key))
} }
})
} }
} }
} }
@ -93,11 +90,9 @@ class RoomStateListController @Inject constructor(
} }
}) })
description(contentJson) description(contentJson)
itemClickAction(GenericItem.Action("view").apply { itemClickAction {
perform = Runnable {
host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent)) host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent))
} }
})
} }
} }
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.discovery package im.vector.app.features.discovery
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
@ -125,7 +124,7 @@ class DiscoverySettingsController @Inject constructor(
id("idServerFooter") id("idServerFooter")
helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer)) helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer))
showCompoundDrawable(true) showCompoundDrawable(true)
itemClickListener(View.OnClickListener { host.listener?.openIdentityServerTerms() }) itemClickListener { host.listener?.openIdentityServerTerms() }
} }
settingsButtonItem { settingsButtonItem {
id("seeTerms") id("seeTerms")

View File

@ -44,7 +44,7 @@ abstract class SettingsButtonItem : EpoxyModelWithHolder<SettingsButtonItem.Hold
@EpoxyAttribute @EpoxyAttribute
var buttonStyle: ButtonStyle = ButtonStyle.POSITIVE var buttonStyle: ButtonStyle = ButtonStyle.POSITIVE
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var buttonClickListener: ClickListener? = null var buttonClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -30,13 +30,13 @@ abstract class SettingsContinueCancelItem : EpoxyModelWithHolder<SettingsContinu
@EpoxyAttribute @EpoxyAttribute
var continueText: String? = null var continueText: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var continueOnClick: ClickListener? = null var continueOnClick: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var canContinue: Boolean = true var canContinue: Boolean = true
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var cancelOnClick: ClickListener? = null var cancelOnClick: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.discovery package im.vector.app.features.discovery
import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
@ -23,7 +22,9 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_settings_helper_info) @EpoxyModelClass(layout = R.layout.item_settings_helper_info)
@ -36,8 +37,8 @@ abstract class SettingsInfoItem : EpoxyModelWithHolder<SettingsInfoItem.Holder>(
@StringRes @StringRes
var helperTextResId: Int? = null var helperTextResId: Int? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickListener: View.OnClickListener? = null var itemClickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
@DrawableRes @DrawableRes
@ -55,7 +56,7 @@ abstract class SettingsInfoItem : EpoxyModelWithHolder<SettingsInfoItem.Holder>(
holder.text.setTextOrHide(helperText) holder.text.setTextOrHide(helperText)
} }
holder.view.setOnClickListener(itemClickListener) holder.view.onClick(itemClickListener)
if (showCompoundDrawable) { if (showCompoundDrawable) {
holder.text.setCompoundDrawablesWithIntrinsicBounds(compoundDrawable, 0, 0, 0) holder.text.setCompoundDrawablesWithIntrinsicBounds(compoundDrawable, 0, 0, 0)

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.discovery package im.vector.app.features.discovery
import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -24,7 +23,9 @@ import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.switchmaterial.SwitchMaterial
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_settings_simple_item) @EpoxyModelClass(layout = R.layout.item_settings_simple_item)
@ -44,8 +45,8 @@ abstract class SettingsItem : EpoxyModelWithHolder<SettingsItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var description: CharSequence? = null var description: CharSequence? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var itemClickListener: View.OnClickListener? = null var itemClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -63,7 +64,7 @@ abstract class SettingsItem : EpoxyModelWithHolder<SettingsItem.Holder>() {
holder.switchButton.isVisible = false holder.switchButton.isVisible = false
holder.view.setOnClickListener(itemClickListener) holder.view.onClick(itemClickListener)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -78,7 +78,7 @@ abstract class SettingsTextButtonSingleLineItem : EpoxyModelWithHolder<SettingsT
@EpoxyAttribute @EpoxyAttribute
var checked: Boolean? = null var checked: Boolean? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var buttonClickListener: ClickListener? = null var buttonClickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute

View File

@ -22,8 +22,10 @@ import androidx.core.graphics.drawable.DrawableCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@EpoxyModelClass(layout = R.layout.item_form_advanced_toggle) @EpoxyModelClass(layout = R.layout.item_form_advanced_toggle)
@ -31,7 +33,7 @@ abstract class FormAdvancedToggleItem : VectorEpoxyModel<FormAdvancedToggleItem.
@EpoxyAttribute lateinit var title: CharSequence @EpoxyAttribute lateinit var title: CharSequence
@EpoxyAttribute var expanded: Boolean = false @EpoxyAttribute var expanded: Boolean = false
@EpoxyAttribute var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -42,7 +44,7 @@ abstract class FormAdvancedToggleItem : VectorEpoxyModel<FormAdvancedToggleItem.
} }
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null) holder.titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null)
holder.titleView.text = title holder.titleView.text = title
holder.view.setOnClickListener { listener?.invoke() } holder.view.onClick(listener)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -26,8 +26,10 @@ import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.TextListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.addTextChangedListenerOnce
import im.vector.app.core.epoxy.setValueOnce import im.vector.app.core.epoxy.setValueOnce
import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.core.platform.SimpleTextWatcher
@ -61,11 +63,10 @@ abstract class FormEditTextItem : VectorEpoxyModel<FormEditTextItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var endIconMode: Int? = null var endIconMode: Int? = null
// FIXME restore EpoxyAttribute.Option.DoNotHash and fix that properly @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
@EpoxyAttribute var onTextChange: TextListener? = null
var onTextChange: ((String) -> Unit)? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var editorActionListener: TextView.OnEditorActionListener? = null var editorActionListener: TextView.OnEditorActionListener? = null
private val onTextChangeListener = object : SimpleTextWatcher() { private val onTextChangeListener = object : SimpleTextWatcher() {
@ -88,7 +89,7 @@ abstract class FormEditTextItem : VectorEpoxyModel<FormEditTextItem.Holder>() {
holder.textInputEditText.isSingleLine = singleLine holder.textInputEditText.isSingleLine = singleLine
holder.textInputEditText.imeOptions = imeOptions ?: EditorInfo.IME_ACTION_NONE holder.textInputEditText.imeOptions = imeOptions ?: EditorInfo.IME_ACTION_NONE
holder.textInputEditText.addTextChangedListener(onTextChangeListener) holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener)
holder.textInputEditText.setOnEditorActionListener(editorActionListener) holder.textInputEditText.setOnEditorActionListener(editorActionListener)
holder.bottomSeparator.isVisible = showBottomSeparator holder.bottomSeparator.isVisible = showBottomSeparator
} }

View File

@ -17,15 +17,18 @@
package im.vector.app.features.form package im.vector.app.features.form
import android.text.Editable import android.text.Editable
import android.view.View
import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatButton
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.TextListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.addTextChangedListenerOnce
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.epoxy.setValueOnce import im.vector.app.core.epoxy.setValueOnce
import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.core.platform.SimpleTextWatcher
@ -44,11 +47,11 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel<FormEditTextWithBut
@EpoxyAttribute @EpoxyAttribute
var buttonText: String? = null var buttonText: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onTextChange: ((String) -> Unit)? = null var onTextChange: TextListener? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onButtonClicked: ((View) -> Unit)? = null var onButtonClicked: ClickListener? = null
private val onTextChangeListener = object : SimpleTextWatcher() { private val onTextChangeListener = object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) { override fun afterTextChanged(s: Editable) {
@ -65,11 +68,10 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel<FormEditTextWithBut
holder.textInputEditText.isEnabled = enabled holder.textInputEditText.isEnabled = enabled
holder.textInputEditText.addTextChangedListener(onTextChangeListener) holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener)
holder.textInputButton.text = buttonText holder.textInputButton.text = buttonText
holder.textInputButton.onClick(onButtonClicked)
holder.textInputButton.setOnClickListener(onButtonClicked)
} }
override fun shouldSaveViewState(): Boolean { override fun shouldSaveViewState(): Boolean {

View File

@ -46,10 +46,10 @@ abstract class FormEditableAvatarItem : EpoxyModelWithHolder<FormEditableAvatarI
@EpoxyAttribute @EpoxyAttribute
var imageUri: Uri? = null var imageUri: Uri? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: ClickListener? = null var clickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var deleteListener: ClickListener? = null var deleteListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -49,10 +49,10 @@ abstract class FormEditableSquareAvatarItem : EpoxyModelWithHolder<FormEditableS
@EpoxyAttribute @EpoxyAttribute
var imageUri: Uri? = null var imageUri: Uri? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: ClickListener? = null var clickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var deleteListener: ClickListener? = null var deleteListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -25,8 +25,10 @@ import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.TextListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.addTextChangedListenerOnce
import im.vector.app.core.epoxy.setValueOnce import im.vector.app.core.epoxy.setValueOnce
import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.core.platform.SimpleTextWatcher
@ -58,7 +60,7 @@ abstract class FormMultiLineEditTextItem : VectorEpoxyModel<FormMultiLineEditTex
var typeFace: Typeface = Typeface.DEFAULT var typeFace: Typeface = Typeface.DEFAULT
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onTextChange: ((String) -> Unit)? = null var onTextChange: TextListener? = null
private val onTextChangeListener = object : SimpleTextWatcher() { private val onTextChangeListener = object : SimpleTextWatcher() {
override fun afterTextChanged(s: Editable) { override fun afterTextChanged(s: Editable) {
@ -80,7 +82,7 @@ abstract class FormMultiLineEditTextItem : VectorEpoxyModel<FormMultiLineEditTex
holder.textInputEditText.isEnabled = enabled holder.textInputEditText.isEnabled = enabled
holder.textInputEditText.addTextChangedListener(onTextChangeListener) holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener)
holder.bottomSeparator.isVisible = showBottomSeparator holder.bottomSeparator.isVisible = showBottomSeparator
} }

View File

@ -39,7 +39,7 @@ abstract class FormSubmitButtonItem : EpoxyModelWithHolder<FormSubmitButtonItem.
@StringRes @StringRes
var buttonTitleId: Int? = null var buttonTitleId: Int? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var buttonClickListener: ClickListener? = null var buttonClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {

View File

@ -22,8 +22,10 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.platform.CheckableConstraintLayout import im.vector.app.core.platform.CheckableConstraintLayout
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -34,11 +36,11 @@ abstract class GroupSummaryItem : VectorEpoxyModel<GroupSummaryItem.Holder>() {
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute lateinit var matrixItem: MatrixItem @EpoxyAttribute lateinit var matrixItem: MatrixItem
@EpoxyAttribute var selected: Boolean = false @EpoxyAttribute var selected: Boolean = false
@EpoxyAttribute var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener { listener?.invoke() } holder.rootView.onClick(listener)
holder.groupNameView.text = matrixItem.displayName holder.groupNameView.text = matrixItem.displayName
holder.rootView.isChecked = selected holder.rootView.isChecked = selected
avatarRenderer.render(matrixItem, holder.avatarImageView) avatarRenderer.render(matrixItem, holder.avatarImageView)

View File

@ -26,8 +26,10 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.platform.CheckableConstraintLayout import im.vector.app.core.platform.CheckableConstraintLayout
import im.vector.app.features.home.room.list.UnreadCounterBadgeView import im.vector.app.features.home.room.list.UnreadCounterBadgeView
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -36,7 +38,7 @@ import im.vector.app.features.themes.ThemeUtils
abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Holder>() { abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Holder>() {
@EpoxyAttribute var selected: Boolean = false @EpoxyAttribute var selected: Boolean = false
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
@EpoxyAttribute var countState : UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false) @EpoxyAttribute var countState : UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false)
@EpoxyAttribute var showSeparator: Boolean = false @EpoxyAttribute var showSeparator: Boolean = false
@ -47,7 +49,7 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Hold
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener { listener?.invoke() } holder.rootView.onClick(listener)
holder.groupNameView.text = holder.view.context.getString(R.string.group_details_home) holder.groupNameView.text = holder.view.context.getString(R.string.group_details_home)
holder.rootView.isChecked = selected holder.rootView.isChecked = selected
holder.rootView.context.resources holder.rootView.context.resources

View File

@ -18,7 +18,6 @@ package im.vector.app.features.home.room.breadcrumbs
import com.airbnb.epoxy.EpoxyController import com.airbnb.epoxy.EpoxyController
import im.vector.app.core.epoxy.zeroItem import im.vector.app.core.epoxy.zeroItem
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject import javax.inject.Inject
@ -53,21 +52,19 @@ class BreadcrumbsController @Inject constructor(
// An empty breadcrumbs list can only be temporary because when entering in a room, // An empty breadcrumbs list can only be temporary because when entering in a room,
// this one is added to the breadcrumbs // this one is added to the breadcrumbs
safeViewState.asyncBreadcrumbs.invoke() safeViewState.asyncBreadcrumbs.invoke()
?.forEach { ?.forEach { roomSummary ->
breadcrumbsItem { breadcrumbsItem {
id(it.roomId) id(roomSummary.roomId)
hasTypingUsers(it.typingUsers.isNotEmpty()) hasTypingUsers(roomSummary.typingUsers.isNotEmpty())
avatarRenderer(host.avatarRenderer) avatarRenderer(host.avatarRenderer)
matrixItem(it.toMatrixItem()) matrixItem(roomSummary.toMatrixItem())
unreadNotificationCount(it.notificationCount) unreadNotificationCount(roomSummary.notificationCount)
showHighlighted(it.highlightCount > 0) showHighlighted(roomSummary.highlightCount > 0)
hasUnreadMessage(it.hasUnreadMessages) hasUnreadMessage(roomSummary.hasUnreadMessages)
hasDraft(it.userDrafts.isNotEmpty()) hasDraft(roomSummary.userDrafts.isNotEmpty())
itemClickListener( itemClickListener {
DebouncedClickListener({ _ -> host.listener?.onBreadcrumbClicked(roomSummary.roomId)
host.listener?.onBreadcrumbClicked(it.roomId) }
})
)
} }
} }
} }

View File

@ -23,8 +23,10 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.list.UnreadCounterBadgeView import im.vector.app.features.home.room.list.UnreadCounterBadgeView
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -39,11 +41,11 @@ abstract class BreadcrumbsItem : VectorEpoxyModel<BreadcrumbsItem.Holder>() {
@EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false
@EpoxyAttribute var hasUnreadMessage: Boolean = false @EpoxyAttribute var hasUnreadMessage: Boolean = false
@EpoxyAttribute var hasDraft: Boolean = false @EpoxyAttribute var hasDraft: Boolean = false
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener(itemClickListener) holder.rootView.onClick(itemClickListener)
holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.unreadIndentIndicator.isVisible = hasUnreadMessage
avatarRenderer.render(matrixItem, holder.avatarImageView) avatarRenderer.render(matrixItem, holder.avatarImageView)
holder.avatarImageView.contentDescription = matrixItem.getBestName() holder.avatarImageView.contentDescription = matrixItem.getBestName()
@ -52,11 +54,6 @@ abstract class BreadcrumbsItem : VectorEpoxyModel<BreadcrumbsItem.Holder>() {
holder.typingIndicator.isVisible = hasTypingUsers holder.typingIndicator.isVisible = hasTypingUsers
} }
override fun unbind(holder: Holder) {
holder.rootView.setOnClickListener(null)
super.unbind(holder)
}
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {
val unreadCounterBadgeView by bind<UnreadCounterBadgeView>(R.id.breadcrumbsUnreadCounterBadgeView) val unreadCounterBadgeView by bind<UnreadCounterBadgeView>(R.id.breadcrumbsUnreadCounterBadgeView)
val unreadIndentIndicator by bind<View>(R.id.breadcrumbsUnreadIndicator) val unreadIndentIndicator by bind<View>(R.id.breadcrumbsUnreadIndicator)

View File

@ -23,7 +23,9 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -33,7 +35,7 @@ abstract class DisplayReadReceiptItem : EpoxyModelWithHolder<DisplayReadReceiptI
@EpoxyAttribute lateinit var matrixItem: MatrixItem @EpoxyAttribute lateinit var matrixItem: MatrixItem
@EpoxyAttribute var timestamp: CharSequence? = null @EpoxyAttribute var timestamp: CharSequence? = null
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute var userClicked: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var userClicked: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -45,7 +47,7 @@ abstract class DisplayReadReceiptItem : EpoxyModelWithHolder<DisplayReadReceiptI
} ?: run { } ?: run {
holder.timestampView.isVisible = false holder.timestampView.isVisible = false
} }
holder.view.setOnClickListener { userClicked?.invoke() } holder.view.onClick(userClicked)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -36,15 +36,15 @@ class DisplayReadReceiptsController @Inject constructor(private val dateFormatte
var listener: Listener? = null var listener: Listener? = null
override fun buildModels(readReceipts: List<ReadReceiptData>) { override fun buildModels(readReceipts: List<ReadReceiptData>) {
readReceipts.forEach { readReceipts.forEach { readReceiptData ->
val timestamp = dateFormatter.format(it.timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME) val timestamp = dateFormatter.format(readReceiptData.timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
DisplayReadReceiptItem_() DisplayReadReceiptItem_()
.id(it.userId) .id(readReceiptData.userId)
.matrixItem(it.toMatrixItem()) .matrixItem(readReceiptData.toMatrixItem())
.avatarRenderer(avatarRender) .avatarRenderer(avatarRender)
.timestamp(timestamp) .timestamp(timestamp)
.userClicked { listener?.didSelectUser(it.userId) } .userClicked { listener?.didSelectUser(readReceiptData.userId) }
.addIf(session.myUserId != it.userId, this) .addIf(session.myUserId != readReceiptData.userId, this)
} }
} }

View File

@ -29,7 +29,7 @@ import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.epoxy.loadingItem
import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.epoxy.noResultItem
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.GenericItemHeader_ import im.vector.app.core.ui.list.GenericHeaderItem_
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
@ -111,7 +111,7 @@ class SearchResultController @Inject constructor(
timeInMillis = eventAndSender.event.originServerTs ?: System.currentTimeMillis() timeInMillis = eventAndSender.event.originServerTs ?: System.currentTimeMillis()
} }
if (lastDate?.get(Calendar.DAY_OF_YEAR) != eventDate.get(Calendar.DAY_OF_YEAR)) { if (lastDate?.get(Calendar.DAY_OF_YEAR) != eventDate.get(Calendar.DAY_OF_YEAR)) {
GenericItemHeader_() GenericHeaderItem_()
.id(eventDate.hashCode()) .id(eventDate.hashCode())
.text(dateFormatter.format(eventDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER)) .text(dateFormatter.format(eventDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER))
.let { result.add(it) } .let { result.add(it) }

View File

@ -36,7 +36,7 @@ abstract class SearchResultItem : VectorEpoxyModel<SearchResultItem.Holder>() {
@EpoxyAttribute var formattedDate: String? = null @EpoxyAttribute var formattedDate: String? = null
@EpoxyAttribute lateinit var spannable: CharSequence @EpoxyAttribute lateinit var spannable: CharSequence
@EpoxyAttribute var sender: MatrixItem? = null @EpoxyAttribute var sender: MatrixItem? = null
@EpoxyAttribute var listener: ClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.home.room.detail.timeline.action package im.vector.app.features.home.room.detail.timeline.action
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
import im.vector.app.EmojiCompatFontProvider import im.vector.app.EmojiCompatFontProvider
@ -169,7 +168,7 @@ class MessageActionsEpoxyController @Inject constructor(
textRes(action.titleRes) textRes(action.titleRes)
showExpand(action is EventSharedAction.ReportContent) showExpand(action is EventSharedAction.ReportContent)
expanded(state.expendedReportContentMenu) expanded(state.expendedReportContentMenu)
listener(View.OnClickListener { host.listener?.didSelectMenuAction(action) }) listener { host.listener?.didSelectMenuAction(action) }
destructive(action.destructive) destructive(action.destructive)
} }
@ -185,7 +184,7 @@ class MessageActionsEpoxyController @Inject constructor(
subMenuItem(true) subMenuItem(true)
iconRes(actionReport.iconResId) iconRes(actionReport.iconResId)
textRes(actionReport.titleRes) textRes(actionReport.titleRes)
listener(View.OnClickListener { host.listener?.didSelectMenuAction(actionReport) }) listener { host.listener?.didSelectMenuAction(actionReport) }
} }
} }
} }

View File

@ -26,8 +26,8 @@ import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.core.ui.list.genericFooterItem
import im.vector.app.core.ui.list.genericHeaderItem
import im.vector.app.core.ui.list.genericItem import im.vector.app.core.ui.list.genericItem
import im.vector.app.core.ui.list.genericItemHeader
import im.vector.app.core.ui.list.genericLoaderItem import im.vector.app.core.ui.list.genericLoaderItem
import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.html.EventHtmlRenderer
import me.gujun.android.span.span import me.gujun.android.span.span
@ -87,7 +87,7 @@ class ViewEditHistoryEpoxyController @Inject constructor(
} }
if (lastDate?.get(Calendar.DAY_OF_YEAR) != evDate.get(Calendar.DAY_OF_YEAR)) { if (lastDate?.get(Calendar.DAY_OF_YEAR) != evDate.get(Calendar.DAY_OF_YEAR)) {
// need to display header with day // need to display header with day
genericItemHeader { genericHeaderItem {
id(evDate.hashCode()) id(evDate.hashCode())
text(host.dateFormatter.format(evDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER)) text(host.dateFormatter.format(evDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER))
} }

View File

@ -29,7 +29,6 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.files.LocalFilesHelper import im.vector.app.core.files.LocalFilesHelper
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.core.utils.containsOnlyEmojis import im.vector.app.core.utils.containsOnlyEmojis
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -322,10 +321,9 @@ class MessageItemFactory @Inject constructor(
if (messageContent.msgType == MessageType.MSGTYPE_STICKER_LOCAL) { if (messageContent.msgType == MessageType.MSGTYPE_STICKER_LOCAL) {
mode(ImageContentRenderer.Mode.STICKER) mode(ImageContentRenderer.Mode.STICKER)
} else { } else {
clickListener( clickListener { view ->
DebouncedClickListener({ view ->
callback?.onImageMessageClicked(messageContent, data, view) callback?.onImageMessageClicked(messageContent, data, view)
})) }
} }
} }
} }

View File

@ -16,7 +16,6 @@
package im.vector.app.features.home.room.detail.timeline.factory package im.vector.app.features.home.room.detail.timeline.factory
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
@ -42,8 +41,8 @@ class ReadReceiptsItemFactory @Inject constructor(private val avatarRenderer: Av
.eventId(eventId) .eventId(eventId)
.readReceipts(readReceiptsData) .readReceipts(readReceiptsData)
.avatarRenderer(avatarRenderer) .avatarRenderer(avatarRenderer)
.clickListener(DebouncedClickListener({ _ -> .clickListener {
callback?.onReadReceiptsClicked(readReceiptsData) callback?.onReadReceiptsClicked(readReceiptsData)
})) }
} }
} }

View File

@ -16,7 +16,6 @@
package im.vector.app.features.home.room.detail.timeline.helper package im.vector.app.features.home.room.detail.timeline.helper
import im.vector.app.EmojiCompatFontProvider import im.vector.app.EmojiCompatFontProvider
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -41,12 +40,12 @@ class MessageItemAttributesFactory @Inject constructor(
itemLongClickListener = { view -> itemLongClickListener = { view ->
callback?.onEventLongClicked(informationData, messageContent, view) ?: false callback?.onEventLongClicked(informationData, messageContent, view) ?: false
}, },
itemClickListener = DebouncedClickListener({ view -> itemClickListener = { view ->
callback?.onEventCellClicked(informationData, messageContent, view) callback?.onEventCellClicked(informationData, messageContent, view)
}), },
memberClickListener = DebouncedClickListener({ memberClickListener = {
callback?.onMemberNameClicked(informationData) callback?.onMemberNameClicked(informationData)
}), },
reactionPillCallback = callback, reactionPillCallback = callback,
avatarCallback = callback, avatarCallback = callback,
readReceiptsCallback = callback, readReceiptsCallback = callback,

View File

@ -23,6 +23,8 @@ import android.widget.TextView
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.core.view.isVisible import androidx.core.view.isVisible
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.core.ui.views.ShieldImageView
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
@ -94,7 +96,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
} }
} }
holder.view.setOnClickListener(baseAttributes.itemClickListener) holder.view.onClick(baseAttributes.itemClickListener)
holder.view.setOnLongClickListener(baseAttributes.itemLongClickListener) holder.view.setOnLongClickListener(baseAttributes.itemLongClickListener)
} }
@ -124,9 +126,9 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
val avatarRenderer: AvatarRenderer val avatarRenderer: AvatarRenderer
val messageColorProvider: MessageColorProvider val messageColorProvider: MessageColorProvider
val itemLongClickListener: View.OnLongClickListener? val itemLongClickListener: View.OnLongClickListener?
val itemClickListener: View.OnClickListener? val itemClickListener: ClickListener?
// val memberClickListener: View.OnClickListener? // val memberClickListener: ClickListener?
val reactionPillCallback: TimelineEventController.ReactionPillCallback? val reactionPillCallback: TimelineEventController.ReactionPillCallback?
// val avatarCallback: TimelineEventController.AvatarCallback? // val avatarCallback: TimelineEventController.AvatarCallback?
@ -139,7 +141,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
// override val avatarRenderer: AvatarRenderer, // override val avatarRenderer: AvatarRenderer,
// override val colorProvider: ColorProvider, // override val colorProvider: ColorProvider,
// override val itemLongClickListener: View.OnLongClickListener? = null, // override val itemLongClickListener: View.OnLongClickListener? = null,
// override val itemClickListener: View.OnClickListener? = null, // override val itemClickListener: ClickListener? = null,
// override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, // override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
// override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null // override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null
// ) : Attributes // ) : Attributes

View File

@ -26,8 +26,9 @@ import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.ui.views.SendStateImageView import im.vector.app.core.ui.views.SendStateImageView
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -44,12 +45,17 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
@EpoxyAttribute @EpoxyAttribute
lateinit var attributes: Attributes lateinit var attributes: Attributes
private val _avatarClickListener = DebouncedClickListener({ private val _avatarClickListener = object : ClickListener {
override fun invoke(p1: View) {
attributes.avatarCallback?.onAvatarClicked(attributes.informationData) attributes.avatarCallback?.onAvatarClicked(attributes.informationData)
}) }
private val _memberNameClickListener = DebouncedClickListener({ }
private val _memberNameClickListener = object : ClickListener {
override fun invoke(p1: View) {
attributes.avatarCallback?.onMemberNameClicked(attributes.informationData) attributes.avatarCallback?.onMemberNameClicked(attributes.informationData)
}) }
}
override fun bind(holder: H) { override fun bind(holder: H) {
super.bind(holder) super.bind(holder)
@ -59,9 +65,9 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
width = attributes.avatarSize width = attributes.avatarSize
} }
holder.avatarImageView.visibility = View.VISIBLE holder.avatarImageView.visibility = View.VISIBLE
holder.avatarImageView.setOnClickListener(_avatarClickListener) holder.avatarImageView.onClick(_avatarClickListener)
holder.memberNameView.visibility = View.VISIBLE holder.memberNameView.visibility = View.VISIBLE
holder.memberNameView.setOnClickListener(_memberNameClickListener) holder.memberNameView.onClick(_memberNameClickListener)
holder.timeView.visibility = View.VISIBLE holder.timeView.visibility = View.VISIBLE
holder.timeView.text = attributes.informationData.time holder.timeView.text = attributes.informationData.time
holder.memberNameView.text = attributes.informationData.memberName holder.memberNameView.text = attributes.informationData.memberName
@ -118,8 +124,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
override val avatarRenderer: AvatarRenderer, override val avatarRenderer: AvatarRenderer,
override val messageColorProvider: MessageColorProvider, override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null, override val itemClickListener: ClickListener? = null,
val memberClickListener: View.OnClickListener? = null, val memberClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
val avatarCallback: TimelineEventController.AvatarCallback? = null, val avatarCallback: TimelineEventController.AvatarCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,

View File

@ -28,6 +28,8 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setLeftDrawable import im.vector.app.core.extensions.setLeftDrawable
import im.vector.app.core.extensions.setTextWithColoredPart import im.vector.app.core.extensions.setTextWithColoredPart
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -64,11 +66,11 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem<CallTileTimelineItem.Ho
} }
if (attributes.callStatus == CallStatus.INVITED && !attributes.informationData.sentByMe && attributes.isStillActive) { if (attributes.callStatus == CallStatus.INVITED && !attributes.informationData.sentByMe && attributes.isStillActive) {
holder.acceptRejectViewGroup.isVisible = true holder.acceptRejectViewGroup.isVisible = true
holder.acceptView.setOnClickListener { holder.acceptView.onClick {
attributes.callback?.onTimelineItemAction(RoomDetailAction.AcceptCall(callId = attributes.callId)) attributes.callback?.onTimelineItemAction(RoomDetailAction.AcceptCall(callId = attributes.callId))
} }
holder.rejectView.setLeftDrawable(R.drawable.ic_call_hangup, R.color.riotx_notice) holder.rejectView.setLeftDrawable(R.drawable.ic_call_hangup, R.color.riotx_notice)
holder.rejectView.setOnClickListener { holder.rejectView.onClick {
attributes.callback?.onTimelineItemAction(RoomDetailAction.EndCall) attributes.callback?.onTimelineItemAction(RoomDetailAction.EndCall)
} }
holder.statusView.isVisible = false holder.statusView.isVisible = false
@ -147,7 +149,7 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem<CallTileTimelineItem.Ho
override val avatarRenderer: AvatarRenderer, override val avatarRenderer: AvatarRenderer,
override val messageColorProvider: MessageColorProvider, override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null
) : AbsBaseMessageItem.Attributes ) : AbsBaseMessageItem.Attributes

View File

@ -31,8 +31,8 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.core.utils.tappableMatchingText import im.vector.app.core.utils.tappableMatchingText
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailAction
@ -172,28 +172,28 @@ abstract class MergedRoomCreationItem : BasedMergedItem<MergedRoomCreationItem.H
holder.roomAvatarImageView.isVisible = roomItem != null holder.roomAvatarImageView.isVisible = roomItem != null
if (roomItem != null) { if (roomItem != null) {
attributes.avatarRenderer.render(roomItem, holder.roomAvatarImageView) attributes.avatarRenderer.render(roomItem, holder.roomAvatarImageView)
holder.roomAvatarImageView.setOnClickListener(DebouncedClickListener({ view -> holder.roomAvatarImageView.onClick { view ->
if (shouldSetAvatar) { if (shouldSetAvatar) {
attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar) attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar)
} else { } else {
// Note: this is no op if there is no avatar on the room // Note: this is no op if there is no avatar on the room
attributes.callback?.onTimelineItemAction(RoomDetailAction.ShowRoomAvatarFullScreen(roomItem, view)) attributes.callback?.onTimelineItemAction(RoomDetailAction.ShowRoomAvatarFullScreen(roomItem, view))
} }
})) }
} }
holder.setAvatarButton.isVisible = shouldSetAvatar holder.setAvatarButton.isVisible = shouldSetAvatar
if (shouldSetAvatar) { if (shouldSetAvatar) {
holder.setAvatarButton.setOnClickListener(DebouncedClickListener({ holder.setAvatarButton.onClick {
attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar) attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar)
})) }
} }
holder.addPeopleButton.isVisible = !isDirect holder.addPeopleButton.isVisible = !isDirect
if (!isDirect) { if (!isDirect) {
holder.addPeopleButton.setOnClickListener(DebouncedClickListener({ holder.addPeopleButton.onClick {
attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionInvitePeople) attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionInvitePeople)
})) }
} }
} }

View File

@ -20,6 +20,7 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import me.saket.bettermovementmethod.BetterLinkMovementMethod import me.saket.bettermovementmethod.BetterLinkMovementMethod
@ -36,7 +37,7 @@ abstract class MessageBlockCodeItem : AbsMessageItem<MessageBlockCodeItem.Holder
super.bind(holder) super.bind(holder)
holder.messageView.text = message holder.messageView.text = message
renderSendState(holder.messageView, holder.messageView) renderSendState(holder.messageView, holder.messageView)
holder.messageView.setOnClickListener(attributes.itemClickListener) holder.messageView.onClick(attributes.itemClickListener)
holder.messageView.setOnLongClickListener(attributes.itemLongClickListener) holder.messageView.setOnLongClickListener(attributes.itemLongClickListener)
holder.editedView.movementMethod = BetterLinkMovementMethod.getInstance() holder.editedView.movementMethod = BetterLinkMovementMethod.getInstance()
holder.editedView.setTextOrHide(editedSpan) holder.editedView.setTextOrHide(editedSpan)

View File

@ -26,6 +26,7 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
@ -43,7 +44,7 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
var iconRes: Int = 0 var iconRes: Int = 0
// @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) // @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
// var clickListener: View.OnClickListener? = null // var clickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var izLocalFile = false var izLocalFile = false
@ -81,9 +82,9 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
} }
// holder.view.setOnClickListener(clickListener) // holder.view.setOnClickListener(clickListener)
holder.filenameView.setOnClickListener(attributes.itemClickListener) holder.filenameView.onClick(attributes.itemClickListener)
holder.filenameView.setOnLongClickListener(attributes.itemLongClickListener) holder.filenameView.setOnLongClickListener(attributes.itemLongClickListener)
holder.fileImageWrapper.setOnClickListener(attributes.itemClickListener) holder.fileImageWrapper.onClick(attributes.itemClickListener)
holder.fileImageWrapper.setOnLongClickListener(attributes.itemLongClickListener) holder.fileImageWrapper.setOnLongClickListener(attributes.itemLongClickListener)
holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG) holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG)
} }

View File

@ -24,6 +24,8 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.files.LocalFilesHelper import im.vector.app.core.files.LocalFilesHelper
import im.vector.app.core.glide.GlideApp import im.vector.app.core.glide.GlideApp
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
@ -42,7 +44,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
var mode = ImageContentRenderer.Mode.THUMBNAIL var mode = ImageContentRenderer.Mode.THUMBNAIL
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: View.OnClickListener? = null var clickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
lateinit var imageContentRenderer: ImageContentRenderer lateinit var imageContentRenderer: ImageContentRenderer
@ -62,10 +64,10 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
} else { } else {
holder.progressLayout.isVisible = false holder.progressLayout.isVisible = false
} }
holder.imageView.setOnClickListener(clickListener) holder.imageView.onClick(clickListener)
holder.imageView.setOnLongClickListener(attributes.itemLongClickListener) holder.imageView.setOnLongClickListener(attributes.itemLongClickListener)
ViewCompat.setTransitionName(holder.imageView, "imagePreview_${id()}") ViewCompat.setTransitionName(holder.imageView, "imagePreview_${id()}")
holder.mediaContentView.setOnClickListener(attributes.itemClickListener) holder.mediaContentView.onClick(attributes.itemClickListener)
holder.mediaContentView.setOnLongClickListener(attributes.itemLongClickListener) holder.mediaContentView.setOnLongClickListener(attributes.itemLongClickListener)
holder.playContentView.visibility = if (playable) View.VISIBLE else View.GONE holder.playContentView.visibility = if (playable) View.VISIBLE else View.GONE
} }

View File

@ -23,6 +23,7 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -59,7 +60,7 @@ abstract class MessageOptionsItem : AbsMessageItem<MessageOptionsItem.Holder>()
as MaterialButton as MaterialButton
holder.buttonContainer.addView(materialButton, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) holder.buttonContainer.addView(materialButton, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
materialButton.text = option.label materialButton.text = option.label
materialButton.setOnClickListener { materialButton.onClick {
callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(relatedEventId, index, option.value ?: "$index")) callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(relatedEventId, index, option.value ?: "$index"))
} }
} }

View File

@ -24,8 +24,9 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import org.matrix.android.sdk.api.session.room.model.message.MessageOptionsContent import org.matrix.android.sdk.api.session.room.model.message.MessageOptionsContent
@ -143,14 +144,16 @@ abstract class MessagePollItem : AbsMessageItem<MessagePollItem.Holder>() {
override fun bindView(itemView: View) { override fun bindView(itemView: View) {
super.bindView(itemView) super.bindView(itemView)
val buttons = listOf(button1, button2, button3, button4, button5) val buttons = listOf(button1, button2, button3, button4, button5)
val clickListener = DebouncedClickListener({ val clickListener = object : ClickListener {
val optionIndex = buttons.indexOf(it) override fun invoke(p1: View) {
val optionIndex = buttons.indexOf(p1)
if (optionIndex != -1 && pollId != null) { if (optionIndex != -1 && pollId != null) {
val compatValue = if (optionIndex < optionValues?.size ?: 0) optionValues?.get(optionIndex) else null val compatValue = if (optionIndex < optionValues?.size ?: 0) optionValues?.get(optionIndex) else null
callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(pollId!!, optionIndex, compatValue ?: "$optionIndex")) callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(pollId!!, optionIndex, compatValue ?: "$optionIndex"))
} }
}) }
buttons.forEach { it.setOnClickListener(clickListener) } }
buttons.forEach { it.onClick(clickListener) }
} }
} }

View File

@ -24,6 +24,7 @@ import androidx.core.widget.TextViewCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
@ -95,7 +96,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
holder.messageView.movementMethod = movementMethod holder.messageView.movementMethod = movementMethod
renderSendState(holder.messageView, holder.messageView) renderSendState(holder.messageView, holder.messageView)
holder.messageView.setOnClickListener(attributes.itemClickListener) holder.messageView.onClick(attributes.itemClickListener)
holder.messageView.setOnLongClickListener(attributes.itemLongClickListener) holder.messageView.setOnLongClickListener(attributes.itemLongClickListener)
if (canUseTextFuture) { if (canUseTextFuture) {

View File

@ -16,12 +16,13 @@
package im.vector.app.features.home.room.detail.timeline.item package im.vector.app.features.home.room.detail.timeline.item
import android.view.View
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.ui.views.ReadReceiptsView import im.vector.app.core.ui.views.ReadReceiptsView
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -31,7 +32,7 @@ abstract class ReadReceiptsItem : EpoxyModelWithHolder<ReadReceiptsItem.Holder>(
@EpoxyAttribute lateinit var eventId: String @EpoxyAttribute lateinit var eventId: String
@EpoxyAttribute lateinit var readReceipts: List<ReadReceiptData> @EpoxyAttribute lateinit var readReceipts: List<ReadReceiptData>
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var clickListener: View.OnClickListener @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var clickListener: ClickListener
override fun canAppendReadMarker(): Boolean = false override fun canAppendReadMarker(): Boolean = false
@ -39,7 +40,8 @@ abstract class ReadReceiptsItem : EpoxyModelWithHolder<ReadReceiptsItem.Holder>(
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.readReceiptsView.render(readReceipts, avatarRenderer, clickListener) holder.readReceiptsView.onClick(clickListener)
holder.readReceiptsView.render(readReceipts, avatarRenderer)
} }
override fun unbind(holder: Holder) { override fun unbind(holder: Holder) {

View File

@ -26,6 +26,7 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -88,7 +89,7 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem<StatusTileTimelineIte
override val avatarRenderer: AvatarRenderer, override val avatarRenderer: AvatarRenderer,
override val messageColorProvider: MessageColorProvider, override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
val emojiTypeFace: Typeface? = null val emojiTypeFace: Typeface? = null

View File

@ -29,8 +29,9 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
@ -111,46 +112,25 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
holder.buttonBar.isVisible = false holder.buttonBar.isVisible = false
} }
holder.callback = callback holder.acceptButton.onClick {
holder.attributes = attributes callback?.onTimelineItemAction(RoomDetailAction.AcceptVerificationRequest(attributes.referenceId, attributes.otherUserId))
}
holder.declineButton.onClick {
callback?.onTimelineItemAction(RoomDetailAction.DeclineVerificationRequest(attributes.referenceId, attributes.otherUserId))
}
renderSendState(holder.view, null, holder.failedToSendIndicator) renderSendState(holder.view, null, holder.failedToSendIndicator)
} }
override fun unbind(holder: Holder) {
super.unbind(holder)
holder.callback = null
holder.attributes = null
}
class Holder : AbsBaseMessageItem.Holder(STUB_ID) { class Holder : AbsBaseMessageItem.Holder(STUB_ID) {
var callback: TimelineEventController.Callback? = null
var attributes: Attributes? = null
private val _clickListener = DebouncedClickListener(View.OnClickListener {
val att = attributes ?: return@OnClickListener
if (it == acceptButton) {
callback?.onTimelineItemAction(RoomDetailAction.AcceptVerificationRequest(att.referenceId, att.otherUserId))
} else if (it == declineButton) {
callback?.onTimelineItemAction(RoomDetailAction.DeclineVerificationRequest(att.referenceId, att.otherUserId))
}
})
val titleView by bind<AppCompatTextView>(R.id.itemVerificationTitleTextView) val titleView by bind<AppCompatTextView>(R.id.itemVerificationTitleTextView)
val descriptionView by bind<AppCompatTextView>(R.id.itemVerificationDetailTextView) val descriptionView by bind<AppCompatTextView>(R.id.itemVerificationDetailTextView)
val buttonBar by bind<ViewGroup>(R.id.itemVerificationButtonBar) val buttonBar by bind<ViewGroup>(R.id.itemVerificationButtonBar)
val statusTextView by bind<TextView>(R.id.itemVerificationStatusText) val statusTextView by bind<TextView>(R.id.itemVerificationStatusText)
val endGuideline by bind<View>(R.id.messageEndGuideline) val endGuideline by bind<View>(R.id.messageEndGuideline)
private val declineButton by bind<Button>(R.id.sas_verification_verified_decline_button) val declineButton by bind<Button>(R.id.sas_verification_verified_decline_button)
private val acceptButton by bind<Button>(R.id.sas_verification_verified_accept_button) val acceptButton by bind<Button>(R.id.sas_verification_verified_accept_button)
val failedToSendIndicator by bind<ImageView>(R.id.messageFailToSendIndicator) val failedToSendIndicator by bind<ImageView>(R.id.messageFailToSendIndicator)
override fun bindView(itemView: View) {
super.bindView(itemView)
acceptButton.setOnClickListener(_clickListener)
declineButton.setOnClickListener(_clickListener)
}
} }
companion object { companion object {
@ -169,8 +149,8 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
override val avatarRenderer: AvatarRenderer, override val avatarRenderer: AvatarRenderer,
override val messageColorProvider: MessageColorProvider, override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null, override val itemClickListener: ClickListener? = null,
// val memberClickListener: View.OnClickListener? = null, // val memberClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
// val avatarCallback: TimelineEventController.AvatarCallback? = null, // val avatarCallback: TimelineEventController.AvatarCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,

View File

@ -27,6 +27,7 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -79,7 +80,7 @@ abstract class WidgetTileTimelineItem : AbsBaseMessageItem<WidgetTileTimelineIte
override val avatarRenderer: AvatarRenderer, override val avatarRenderer: AvatarRenderer,
override val messageColorProvider: MessageColorProvider, override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
val emojiTypeFace: Typeface? = null val emojiTypeFace: Typeface? = null

View File

@ -22,7 +22,9 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
/** /**
* Item displaying an emoji reaction (single line with emoji, author, time) * Item displaying an emoji reaction (single line with emoji, author, time)
@ -39,8 +41,8 @@ abstract class ReactionInfoSimpleItem : EpoxyModelWithHolder<ReactionInfoSimpleI
@EpoxyAttribute @EpoxyAttribute
var timeStamp: CharSequence? = null var timeStamp: CharSequence? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var userClicked: (() -> Unit)? = null var userClicked: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -52,7 +54,7 @@ abstract class ReactionInfoSimpleItem : EpoxyModelWithHolder<ReactionInfoSimpleI
} ?: run { } ?: run {
holder.timeStampView.isVisible = false holder.timeStampView.isVisible = false
} }
holder.view.setOnClickListener { userClicked?.invoke() } holder.view.onClick(userClicked)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -52,13 +52,13 @@ class ViewReactionsEpoxyController @Inject constructor(
} }
} }
is Success -> { is Success -> {
state.mapReactionKeyToMemberList()?.forEach { state.mapReactionKeyToMemberList()?.forEach { reactionInfo ->
reactionInfoSimpleItem { reactionInfoSimpleItem {
id(it.eventId) id(reactionInfo.eventId)
timeStamp(it.timestamp) timeStamp(reactionInfo.timestamp)
reactionKey(host.emojiCompatWrapper.safeEmojiSpanify(it.reactionKey)) reactionKey(host.emojiCompatWrapper.safeEmojiSpanify(reactionInfo.reactionKey))
authorDisplayName(it.authorName ?: it.authorId) authorDisplayName(reactionInfo.authorName ?: reactionInfo.authorId)
userClicked { host.listener?.didSelectUser(it.authorId) } userClicked { host.listener?.didSelectUser(reactionInfo.authorId) }
} }
} }
} }

View File

@ -35,7 +35,7 @@ import java.net.URL
abstract class RoomWidgetItem : EpoxyModelWithHolder<RoomWidgetItem.Holder>() { abstract class RoomWidgetItem : EpoxyModelWithHolder<RoomWidgetItem.Holder>() {
@EpoxyAttribute lateinit var widget: Widget @EpoxyAttribute lateinit var widget: Widget
@EpoxyAttribute var widgetClicked: ClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var widgetClicked: ClickListener? = null
@DrawableRes @DrawableRes
@EpoxyAttribute var iconRes: Int? = null @EpoxyAttribute var iconRes: Int? = null

View File

@ -16,7 +16,6 @@
package im.vector.app.features.home.room.detail.widget package im.vector.app.features.home.room.detail.widget
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
@ -44,11 +43,11 @@ class RoomWidgetsController @Inject constructor(
text(host.stringProvider.getString(R.string.room_no_active_widgets)) text(host.stringProvider.getString(R.string.room_no_active_widgets))
} }
} else { } else {
widgets.forEach { widgets.forEach { widget ->
roomWidgetItem { roomWidgetItem {
id(it.widgetId) id(widget.widgetId)
widget(it) widget(widget)
widgetClicked { host.listener?.didSelectWidget(it) } widgetClicked { host.listener?.didSelectWidget(widget) }
} }
} }
} }
@ -56,7 +55,7 @@ class RoomWidgetsController @Inject constructor(
id("addIntegration") id("addIntegration")
text(host.stringProvider.getString(R.string.room_manage_integrations)) text(host.stringProvider.getString(R.string.room_manage_integrations))
textColor(host.colorProvider.getColor(R.color.riotx_accent)) textColor(host.colorProvider.getColor(R.color.riotx_accent))
buttonClickAction(View.OnClickListener { host.listener?.didSelectManageWidgets() }) buttonClickAction { host.listener?.didSelectManageWidgets() }
} }
} }

View File

@ -22,6 +22,7 @@ import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.room.list.widget.NotifsFabMenuView import im.vector.app.features.home.room.list.widget.NotifsFabMenuView
@EpoxyModelClass(layout = R.layout.item_room_filter_footer) @EpoxyModelClass(layout = R.layout.item_room_filter_footer)
@ -35,9 +36,9 @@ abstract class FilteredRoomFooterItem : VectorEpoxyModel<FilteredRoomFooterItem.
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.createRoomButton.setOnClickListener { listener?.createRoom(currentFilter) } holder.createRoomButton.onClick { listener?.createRoom(currentFilter) }
holder.createDirectChat.setOnClickListener { listener?.createDirectChat() } holder.createDirectChat.onClick { listener?.createDirectChat() }
holder.openRoomDirectory.setOnClickListener { listener?.openRoomDirectory(currentFilter) } holder.openRoomDirectory.onClick { listener?.openRoomDirectory(currentFilter) }
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -23,8 +23,10 @@ import androidx.core.graphics.drawable.DrawableCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@EpoxyModelClass(layout = R.layout.item_room_category) @EpoxyModelClass(layout = R.layout.item_room_category)
@ -34,7 +36,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
@EpoxyAttribute var expanded: Boolean = false @EpoxyAttribute var expanded: Boolean = false
@EpoxyAttribute var unreadNotificationCount: Int = 0 @EpoxyAttribute var unreadNotificationCount: Int = 0
@EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false
@EpoxyAttribute var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -46,7 +48,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null) holder.titleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null)
holder.titleView.text = title holder.titleView.text = title
holder.rootView.setOnClickListener { listener?.invoke() } holder.rootView.onClick(listener)
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -22,8 +22,10 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.ButtonStateView import im.vector.app.core.platform.ButtonStateView
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -37,36 +39,16 @@ abstract class RoomInvitationItem : VectorEpoxyModel<RoomInvitationItem.Holder>(
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute lateinit var matrixItem: MatrixItem @EpoxyAttribute lateinit var matrixItem: MatrixItem
@EpoxyAttribute var secondLine: CharSequence? = null @EpoxyAttribute var secondLine: CharSequence? = null
@EpoxyAttribute var listener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
@EpoxyAttribute lateinit var changeMembershipState: ChangeMembershipState @EpoxyAttribute lateinit var changeMembershipState: ChangeMembershipState
@EpoxyAttribute var acceptListener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var acceptListener: ClickListener? = null
@EpoxyAttribute var rejectListener: (() -> Unit)? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var rejectListener: ClickListener? = null
private val acceptCallback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
acceptListener?.invoke()
}
override fun onRetryClicked() {
acceptListener?.invoke()
}
}
private val rejectCallback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
rejectListener?.invoke()
}
override fun onRetryClicked() {
rejectListener?.invoke()
}
}
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener { listener?.invoke() } holder.rootView.onClick(listener)
holder.acceptView.callback = acceptCallback holder.acceptView.commonClicked = acceptListener
holder.rejectView.callback = rejectCallback holder.rejectView.commonClicked = rejectListener
InviteButtonStateBinder.bind(holder.acceptView, holder.rejectView, changeMembershipState) InviteButtonStateBinder.bind(holder.acceptView, holder.rejectView, changeMembershipState)
holder.titleView.text = matrixItem.getBestName() holder.titleView.text = matrixItem.getBestName()
holder.subtitleView.setTextOrHide(secondLine) holder.subtitleView.setTextOrHide(secondLine)

View File

@ -28,8 +28,10 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.core.ui.views.ShieldImageView
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -57,12 +59,12 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
@EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false
@EpoxyAttribute var hasFailedSending: Boolean = false @EpoxyAttribute var hasFailedSending: Boolean = false
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null
@EpoxyAttribute var showSelected: Boolean = false @EpoxyAttribute var showSelected: Boolean = false
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener(itemClickListener) holder.rootView.onClick(itemClickListener)
holder.rootView.setOnLongClickListener { holder.rootView.setOnLongClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
itemLongClickListener?.onLongClick(it) ?: false itemLongClickListener?.onLongClick(it) ?: false

View File

@ -23,7 +23,6 @@ import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.DebouncedClickListener
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter
import im.vector.app.features.home.room.typing.TypingHelper import im.vector.app.features.home.room.typing.TypingHelper
@ -64,8 +63,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
.buttonLabel(stringProvider.getString(R.string.join)) .buttonLabel(stringProvider.getString(R.string.join))
.loading(suggestedRoomJoiningStates[spaceChildInfo.childRoomId] is Loading) .loading(suggestedRoomJoiningStates[spaceChildInfo.childRoomId] is Loading)
.memberCount(spaceChildInfo.activeMemberCount ?: 0) .memberCount(spaceChildInfo.activeMemberCount ?: 0)
.buttonClickListener(DebouncedClickListener({ listener?.onJoinSuggestedRoom(spaceChildInfo) })) .buttonClickListener { listener?.onJoinSuggestedRoom(spaceChildInfo) }
.itemClickListener(DebouncedClickListener({ listener?.onSuggestedRoomClicked(spaceChildInfo) })) .itemClickListener { listener?.onSuggestedRoomClicked(spaceChildInfo) }
} }
private fun createInvitationItem(roomSummary: RoomSummary, private fun createInvitationItem(roomSummary: RoomSummary,
@ -127,10 +126,6 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
.itemLongClickListener { _ -> .itemLongClickListener { _ ->
onLongClick?.invoke(roomSummary) ?: false onLongClick?.invoke(roomSummary) ?: false
} }
.itemClickListener( .itemClickListener { onClick?.invoke(roomSummary) }
DebouncedClickListener({
onClick?.invoke(roomSummary)
})
)
} }
} }

View File

@ -22,12 +22,13 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.utils.DebouncedClickListener import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
import im.vector.app.databinding.ItemRoomCategoryBinding import im.vector.app.databinding.ItemRoomCategoryBinding
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
class SectionHeaderAdapter constructor( class SectionHeaderAdapter constructor(
private val onClickAction: (() -> Unit) private val onClickAction: ClickListener
) : RecyclerView.Adapter<SectionHeaderAdapter.VH>() { ) : RecyclerView.Adapter<SectionHeaderAdapter.VH>() {
data class RoomsSectionData( data class RoomsSectionData(
@ -59,7 +60,7 @@ class SectionHeaderAdapter constructor(
override fun getItemViewType(position: Int) = R.layout.item_room_category override fun getItemViewType(position: Int) = R.layout.item_room_category
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
return VH.create(parent, this.onClickAction) return VH.create(parent, onClickAction)
} }
override fun onBindViewHolder(holder: VH, position: Int) { override fun onBindViewHolder(holder: VH, position: Int) {
@ -70,13 +71,11 @@ class SectionHeaderAdapter constructor(
class VH constructor( class VH constructor(
private val binding: ItemRoomCategoryBinding, private val binding: ItemRoomCategoryBinding,
onClickAction: (() -> Unit) onClickAction: ClickListener
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
init { init {
binding.root.setOnClickListener(DebouncedClickListener({ binding.root.onClick(onClickAction)
onClickAction.invoke()
}))
} }
fun bind(roomsSectionData: RoomsSectionData) { fun bind(roomsSectionData: RoomsSectionData) {
@ -91,7 +90,7 @@ class SectionHeaderAdapter constructor(
} }
companion object { companion object {
fun create(parent: ViewGroup, onClickAction: () -> Unit): VH { fun create(parent: ViewGroup, onClickAction: ClickListener): VH {
val view = LayoutInflater.from(parent.context) val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_room_category, parent, false) .inflate(R.layout.item_room_category, parent, false)
val binding = ItemRoomCategoryBinding.bind(view) val binding = ItemRoomCategoryBinding.bind(view)

View File

@ -29,8 +29,10 @@ import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
import me.gujun.android.span.image import me.gujun.android.span.image
@ -52,12 +54,12 @@ abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>(
@EpoxyAttribute var buttonLabel: String? = null @EpoxyAttribute var buttonLabel: String? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var buttonClickListener: View.OnClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var buttonClickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener(itemClickListener) holder.rootView.onClick(itemClickListener)
holder.rootView.setOnLongClickListener { holder.rootView.setOnLongClickListener {
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
itemLongClickListener?.onLongClick(it) ?: false itemLongClickListener?.onLongClick(it) ?: false
@ -95,11 +97,12 @@ abstract class SpaceChildInfoItem : VectorEpoxyModel<SpaceChildInfoItem.Holder>(
holder.joinButton.isVisible = true holder.joinButton.isVisible = true
} }
holder.joinButton.setOnClickListener { holder.joinButton.onClick {
// local echo // local echo
holder.joinButton.isEnabled = false holder.joinButton.isEnabled = false
// FIXME It may lead to crash if the view is gone
holder.view.postDelayed({ holder.joinButton.isEnabled = true }, 400) holder.view.postDelayed({ holder.joinButton.isEnabled = true }, 400)
buttonClickListener?.onClick(it) buttonClickListener?.invoke(it)
} }
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.app.features.home.room.list.actions package im.vector.app.features.home.room.list.actions
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
import im.vector.app.core.epoxy.bottomsheet.bottomSheetRoomPreviewItem import im.vector.app.core.epoxy.bottomsheet.bottomSheetRoomPreviewItem
@ -87,7 +86,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
iconRes(iconResId) iconRes(iconResId)
textRes(titleRes) textRes(titleRes)
destructive(this@toBottomSheetItem.destructive) destructive(this@toBottomSheetItem.destructive)
listener(View.OnClickListener { host.listener?.didSelectMenuAction(this@toBottomSheetItem) }) listener { host.listener?.didSelectMenuAction(this@toBottomSheetItem) }
} }
} }

View File

@ -23,10 +23,8 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.platform.ButtonStateView
import im.vector.app.databinding.VectorInviteViewBinding import im.vector.app.databinding.VectorInviteViewBinding
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
@ -56,25 +54,8 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
} }
inflate(context, R.layout.vector_invite_view, this) inflate(context, R.layout.vector_invite_view, this)
views = VectorInviteViewBinding.bind(this) views = VectorInviteViewBinding.bind(this)
views.inviteAcceptView.callback = object : ButtonStateView.Callback { views.inviteAcceptView.commonClicked = { callback?.onAcceptInvite() }
override fun onButtonClicked() { views.inviteRejectView.commonClicked = { callback?.onRejectInvite() }
callback?.onAcceptInvite()
}
override fun onRetryClicked() {
callback?.onAcceptInvite()
}
}
views.inviteRejectView.callback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
callback?.onRejectInvite()
}
override fun onRetryClicked() {
callback?.onRejectInvite()
}
}
} }
fun render(sender: RoomMemberSummary, mode: Mode = Mode.LARGE, changeMembershipState: ChangeMembershipState) { fun render(sender: RoomMemberSummary, mode: Mode = Mode.LARGE, changeMembershipState: ChangeMembershipState) {

View File

@ -16,7 +16,6 @@
package im.vector.app.features.login.terms package im.vector.app.features.login.terms
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.epoxy.TypedEpoxyController
import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms
import javax.inject.Inject import javax.inject.Inject
@ -35,8 +34,7 @@ class PolicyController @Inject constructor() : TypedEpoxyController<List<Localiz
checked(entry.checked) checked(entry.checked)
title(entry.localizedFlowDataLoginTerms.localizedName) title(entry.localizedFlowDataLoginTerms.localizedName)
subtitle(host.homeServer) subtitle(host.homeServer)
clickListener { host.listener?.openPolicy(entry.localizedFlowDataLoginTerms) }
clickListener(View.OnClickListener { host.listener?.openPolicy(entry.localizedFlowDataLoginTerms) })
checkChangeListener { _, isChecked -> checkChangeListener { _, isChecked ->
host.listener?.setChecked(entry.localizedFlowDataLoginTerms, isChecked) host.listener?.setChecked(entry.localizedFlowDataLoginTerms, isChecked)
} }

View File

@ -16,7 +16,6 @@
package im.vector.app.features.login.terms package im.vector.app.features.login.terms
import android.view.View
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.TextView import android.widget.TextView
@ -24,7 +23,9 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
@EpoxyModelClass(layout = R.layout.item_policy) @EpoxyModelClass(layout = R.layout.item_policy)
abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() { abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() {
@ -41,7 +42,7 @@ abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() {
var checkChangeListener: CompoundButton.OnCheckedChangeListener? = null var checkChangeListener: CompoundButton.OnCheckedChangeListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickListener: View.OnClickListener? = null var clickListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
@ -50,7 +51,7 @@ abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() {
it.checkbox.setOnCheckedChangeListener(checkChangeListener) it.checkbox.setOnCheckedChangeListener(checkChangeListener)
it.title.text = title it.title.text = title
it.subtitle.text = subtitle it.subtitle.text = subtitle
it.view.setOnClickListener(clickListener) it.view.onClick(clickListener)
} }
} }

View File

@ -51,19 +51,8 @@ class MatrixToRoomSpaceFragment @Inject constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
views.matrixToCardMainButton.callback = object : ButtonStateView.Callback { views.matrixToCardMainButton.commonClicked = { mainButtonClicked() }
override fun onButtonClicked() { views.matrixToCardSecondaryButton.commonClicked = { secondaryButtonClicked() }
mainButtonClicked()
}
override fun onRetryClicked() = onButtonClicked()
}
views.matrixToCardSecondaryButton.callback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
secondaryButtonClicked()
}
override fun onRetryClicked() = onButtonClicked()
}
} }
override fun invalidate() = withState(sharedViewModel) { state -> override fun invalidate() = withState(sharedViewModel) { state ->

View File

@ -63,13 +63,13 @@ class EmojiSearchResultController @Inject constructor(
} }
} else { } else {
// Build the search results // Build the search results
results.forEach { results.forEach { emojiItem ->
emojiSearchResultItem { emojiSearchResultItem {
id(it.name) id(emojiItem.name)
emojiItem(it) emojiItem(emojiItem)
emojiTypeFace(host.emojiTypeface) emojiTypeFace(host.emojiTypeface)
currentQuery(data.query) currentQuery(data.query)
onClickListener(host.listener) onClickListener { host.listener?.onReactionSelected(emojiItem.emoji) }
} }
} }
} }

View File

@ -21,7 +21,9 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.reactions.data.EmojiItem import im.vector.app.features.reactions.data.EmojiItem
@ -34,8 +36,8 @@ abstract class EmojiSearchResultItem : EpoxyModelWithHolder<EmojiSearchResultIte
@EpoxyAttribute @EpoxyAttribute
var currentQuery: String? = null var currentQuery: String? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onClickListener: ReactionClickListener? = null var onClickListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute
var emojiTypeFace: Typeface? = null var emojiTypeFace: Typeface? = null
@ -47,9 +49,7 @@ abstract class EmojiSearchResultItem : EpoxyModelWithHolder<EmojiSearchResultIte
holder.emojiText.typeface = emojiTypeFace ?: Typeface.DEFAULT holder.emojiText.typeface = emojiTypeFace ?: Typeface.DEFAULT
holder.emojiNameText.text = emojiItem.name holder.emojiNameText.text = emojiItem.name
holder.emojiKeywordText.setTextOrHide(emojiItem.keywords.joinToString()) holder.emojiKeywordText.setTextOrHide(emojiItem.keywords.joinToString())
holder.view.setOnClickListener { holder.view.onClick(onClickListener)
onClickListener?.onReactionSelected(emojiItem.emoji)
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -22,8 +22,10 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.ButtonStateView import im.vector.app.core.platform.ButtonStateView
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -50,15 +52,15 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
var joinState: JoinState = JoinState.NOT_JOINED var joinState: JoinState = JoinState.NOT_JOINED
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var globalListener: (() -> Unit)? = null var globalListener: ClickListener? = null
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var joinListener: (() -> Unit)? = null var joinListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener { globalListener?.invoke() } holder.rootView.onClick(globalListener)
avatarRenderer.render(matrixItem, holder.avatarView) avatarRenderer.render(matrixItem, holder.avatarView)
holder.nameView.text = matrixItem.displayName holder.nameView.text = matrixItem.displayName
@ -76,16 +78,7 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
} }
) )
holder.buttonState.callback = object : ButtonStateView.Callback { holder.buttonState.commonClicked = { joinListener?.invoke(it) }
override fun onButtonClicked() {
joinListener?.invoke()
}
override fun onRetryClicked() {
// Same action
onButtonClicked()
}
}
} }
class Holder : VectorEpoxyHolder() { class Holder : VectorEpoxyHolder() {

View File

@ -22,8 +22,10 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -36,12 +38,12 @@ abstract class UnknownRoomItem : VectorEpoxyModel<UnknownRoomItem.Holder>() {
@EpoxyAttribute @EpoxyAttribute
lateinit var matrixItem: MatrixItem lateinit var matrixItem: MatrixItem
@EpoxyAttribute @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var globalListener: (() -> Unit)? = null var globalListener: ClickListener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder) super.bind(holder)
holder.rootView.setOnClickListener { globalListener?.invoke() } holder.rootView.onClick(globalListener)
avatarRenderer.render(matrixItem, holder.avatarView) avatarRenderer.render(matrixItem, holder.avatarView)
holder.nameView.text = matrixItem.displayName holder.nameView.text = matrixItem.displayName
} }

Some files were not shown because too many files have changed in this diff Show More