diff --git a/newsfragment/3435.feature b/newsfragment/3435.feature new file mode 100644 index 0000000000..222092924d --- /dev/null +++ b/newsfragment/3435.feature @@ -0,0 +1 @@ +Cleanup Epoxy items, and debounce all the clicks \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ErrorWithRetryItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ErrorWithRetryItem.kt index f555a70d3f..8d2b2be6c2 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/ErrorWithRetryItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/ErrorWithRetryItem.kt @@ -29,14 +29,14 @@ abstract class ErrorWithRetryItem : VectorEpoxyModel( @EpoxyAttribute var text: String? = null - @EpoxyAttribute - var listener: (() -> Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var listener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) holder.textView.text = text holder.buttonView.isVisible = listener != null - holder.buttonView.setOnClickListener { listener?.invoke() } + holder.buttonView.onClick(listener) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/core/epoxy/Listener.kt b/vector/src/main/java/im/vector/app/core/epoxy/Listener.kt index e271b5abb5..e959d800b8 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/Listener.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/Listener.kt @@ -17,12 +17,22 @@ package im.vector.app.core.epoxy 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?) { - setOnClickListener { listener?.invoke() } + if (listener == null) { + setOnClickListener(null) + } else { + setOnClickListener(DebouncedClickListener(listener)) + } } + +/** + * Simple Text listener lambda + */ +typealias TextListener = (String) -> Unit diff --git a/vector/src/main/java/im/vector/app/core/epoxy/VectorEpoxyFormExt.kt b/vector/src/main/java/im/vector/app/core/epoxy/VectorEpoxyFormExt.kt index f93b07a98d..4bc40ce557 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/VectorEpoxyFormExt.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/VectorEpoxyFormExt.kt @@ -16,7 +16,9 @@ package im.vector.app.core.epoxy +import android.text.TextWatcher import android.widget.CompoundButton +import android.widget.TextView import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.textfield.TextInputEditText @@ -39,3 +41,9 @@ fun VectorEpoxyHolder.setValueOnce(switchView: SwitchMaterial, switchChecked: Bo switchView.setOnCheckedChangeListener(listener) } } + +fun TextView.addTextChangedListenerOnce(textWatcher: TextWatcher) { + // Ensure the watcher is not added multiple times + removeTextChangedListener(textWatcher) + addTextChangedListener(textWatcher) +} diff --git a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetActionItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetActionItem.kt index 80792648f6..c3aaede109 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetActionItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetActionItem.kt @@ -30,8 +30,10 @@ import androidx.core.widget.ImageViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.features.themes.ThemeUtils /** @@ -69,14 +71,12 @@ abstract class BottomSheetActionItem : VectorEpoxyModel Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var userClicked: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) avatarRenderer.render(matrixItem, holder.avatar) - holder.avatar.setOnClickListener { userClicked?.invoke() } - holder.sender.setOnClickListener { userClicked?.invoke() } + holder.avatar.onClick(userClicked) + holder.sender.onClick(userClicked) holder.sender.setTextOrHide(matrixItem.displayName) data?.let { imageContentRenderer?.render(it, ImageContentRenderer.Mode.THUMBNAIL, holder.imagePreview) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetQuickReactionsItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetQuickReactionsItem.kt index ca8ef89c68..3f6b23a85f 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetQuickReactionsItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetQuickReactionsItem.kt @@ -24,6 +24,7 @@ import im.vector.app.EmojiCompatFontProvider import im.vector.app.R import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick /** * A quick reaction list for bottom sheet. @@ -50,7 +51,7 @@ abstract class BottomSheetQuickReactionsItem : VectorEpoxyModel : VectorEpoxy @EpoxyAttribute var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null - @EpoxyAttribute var clickListener: View.OnClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null @CallSuper override fun bind(holder: T) { @@ -43,7 +46,7 @@ abstract class BaseProfileMatrixItem : VectorEpoxy .takeIf { it != bestName } // Special case for ThreePid fake matrix item .takeIf { it != "@" } - holder.view.setOnClickListener(clickListener?.takeIf { editable }) + holder.view.onClick(clickListener?.takeIf { editable }) holder.titleView.text = bestName holder.subtitleView.setTextOrHide(matrixId) holder.editableView.isVisible = editable diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/ProfileActionItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/ProfileActionItem.kt index 2769121afa..2b4c859879 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/profiles/ProfileActionItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/ProfileActionItem.kt @@ -67,7 +67,7 @@ abstract class ProfileActionItem : VectorEpoxyModel() @EpoxyAttribute var destructive: Boolean = false - @EpoxyAttribute + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null override fun bind(holder: Holder) { diff --git a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt index fe187a915e..ee2933f542 100755 --- a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt @@ -24,6 +24,8 @@ import android.widget.FrameLayout import androidx.core.view.isInvisible import androidx.core.view.isVisible 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 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() } - var callback: Callback? = null - - interface Callback { - fun onButtonClicked() - fun onRetryClicked() - } + var commonClicked: ClickListener? = null + var buttonClicked: ClickListener? = null + var retryClicked: ClickListener? = null // Big or Flat 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) - views.buttonStateRetry.setOnClickListener { - callback?.onRetryClicked() + views.buttonStateRetry.onClick { + commonClicked?.invoke(it) + retryClicked?.invoke(it) } // Read attributes @@ -80,8 +80,9 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu } } - button.setOnClickListener { - callback?.onButtonClicked() + button.onClick { + commonClicked?.invoke(it) + buttonClicked?.invoke(it) } } diff --git a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt index 5edaa3400b..ab1480b635 100644 --- a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt +++ b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt @@ -15,7 +15,6 @@ */ package im.vector.app.core.ui.bottomsheet -import android.view.View import com.airbnb.epoxy.TypedEpoxyController /** @@ -51,7 +50,7 @@ abstract class BottomSheetGenericController action.toRadioBottomSheetItem() - .listener(View.OnClickListener { listener?.didSelectAction(action) }) + .listener { listener?.didSelectAction(action) } .addTo(this) } } diff --git a/vector/src/main/java/im/vector/app/core/ui/list/Action.kt b/vector/src/main/java/im/vector/app/core/ui/list/Action.kt new file mode 100644 index 0000000000..f20ef84f54 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/ui/list/Action.kt @@ -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 +) diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt index d1df785381..867edfe9cc 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt @@ -15,15 +15,16 @@ */ package im.vector.app.core.ui.list -import android.view.View import androidx.annotation.ColorInt import androidx.annotation.DrawableRes import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.google.android.material.button.MaterialButton 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.features.themes.ThemeUtils /** @@ -35,8 +36,8 @@ abstract class GenericButtonItem : VectorEpoxyModel() @EpoxyAttribute var text: String? = null - @EpoxyAttribute - var buttonClickAction: View.OnClickListener? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var buttonClickAction: ClickListener? = null @EpoxyAttribute @ColorInt @@ -57,7 +58,7 @@ abstract class GenericButtonItem : VectorEpoxyModel() holder.button.icon = null } - buttonClickAction?.let { holder.button.setOnClickListener(it) } + holder.button.onClick(buttonClickAction) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericEmptyWithActionItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericEmptyWithActionItem.kt index f8eb968268..359488e3f4 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericEmptyWithActionItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericEmptyWithActionItem.kt @@ -29,6 +29,7 @@ import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick 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) abstract class GenericEmptyWithActionItem : VectorEpoxyModel() { - class Action(var title: String) { - var perform: Runnable? = null - } - @EpoxyAttribute var title: CharSequence? = null @@ -77,9 +74,7 @@ abstract class GenericEmptyWithActionItem : VectorEpoxyModel() @EpoxyAttribute var style: ItemStyle = ItemStyle.NORMAL_TEXT - @EpoxyAttribute - var itemClickAction: GenericItem.Action? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickAction: ClickListener? = null @EpoxyAttribute var centered: Boolean = true @@ -65,9 +67,7 @@ abstract class GenericFooterItem : VectorEpoxyModel() holder.text.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)) } - holder.view.setOnClickListener { - itemClickAction?.perform?.run() - } + holder.view.onClick(itemClickAction) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericItemHeader.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericHeaderItem.kt similarity index 95% rename from vector/src/main/java/im/vector/app/core/ui/list/GenericItemHeader.kt rename to vector/src/main/java/im/vector/app/core/ui/list/GenericHeaderItem.kt index bc5446e836..b4b0211b91 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericItemHeader.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericHeaderItem.kt @@ -29,7 +29,7 @@ import im.vector.app.features.themes.ThemeUtils * A generic list item header left aligned with notice color. */ @EpoxyModelClass(layout = R.layout.item_generic_header) -abstract class GenericItemHeader : VectorEpoxyModel() { +abstract class GenericHeaderItem : VectorEpoxyModel() { @EpoxyAttribute var text: String? = null diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericItem.kt index 8a01183915..cdfd1d75fc 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericItem.kt @@ -25,8 +25,10 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick 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) abstract class GenericItem : VectorEpoxyModel() { - class Action(var title: String) { - var perform: Runnable? = null - } - @EpoxyAttribute var title: CharSequence? = null @@ -68,8 +66,8 @@ abstract class GenericItem : VectorEpoxyModel() { @EpoxyAttribute var destructiveButtonAction: Action? = null - @EpoxyAttribute - var itemClickAction: Action? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickAction: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -100,18 +98,12 @@ abstract class GenericItem : VectorEpoxyModel() { } holder.actionButton.setTextOrHide(buttonAction?.title) - holder.actionButton.setOnClickListener { - buttonAction?.perform?.run() - } + holder.actionButton.onClick(buttonAction?.listener) holder.destructiveButton.setTextOrHide(destructiveButtonAction?.title) - holder.destructiveButton.setOnClickListener { - destructiveButtonAction?.perform?.run() - } + holder.destructiveButton.onClick(destructiveButtonAction?.listener) - holder.root.setOnClickListener { - itemClickAction?.perform?.run() - } + holder.root.onClick(itemClickAction) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericPillItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericPillItem.kt index ce9e35c007..c522d53209 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericPillItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericPillItem.kt @@ -25,8 +25,10 @@ import androidx.core.widget.ImageViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.themes.ThemeUtils @@ -42,8 +44,8 @@ abstract class GenericPillItem : VectorEpoxyModel() { @EpoxyAttribute var style: ItemStyle = ItemStyle.NORMAL_TEXT - @EpoxyAttribute - var itemClickAction: GenericItem.Action? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickAction: ClickListener? = null @EpoxyAttribute var centered: Boolean = false @@ -76,9 +78,7 @@ abstract class GenericPillItem : VectorEpoxyModel() { ImageViewCompat.setImageTintList(holder.imageView, null) } - holder.view.setOnClickListener { - itemClickAction?.perform?.run() - } + holder.view.onClick(itemClickAction) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericPositiveButtonItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericPositiveButtonItem.kt index d18adde4ba..753b085d99 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericPositiveButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericPositiveButtonItem.kt @@ -15,15 +15,16 @@ */ package im.vector.app.core.ui.list -import android.view.View import androidx.annotation.ColorInt import androidx.annotation.DrawableRes import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.google.android.material.button.MaterialButton 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick /** * A generic button list item. @@ -34,8 +35,8 @@ abstract class GenericPositiveButtonItem : VectorEpoxyModel() { +abstract class GenericWithValueItem : VectorEpoxyModel() { @EpoxyAttribute var title: CharSequence? = null @@ -53,10 +54,10 @@ abstract class GenericItemWithValue : VectorEpoxyModel, avatarRenderer: AvatarRenderer, clickListener: OnClickListener) { - setOnClickListener(clickListener) + fun render(readReceipts: List, avatarRenderer: AvatarRenderer) { if (readReceipts.isNotEmpty()) { isVisible = true for (index in 0 until MAX_RECEIPT_DISPLAYED) { diff --git a/vector/src/main/java/im/vector/app/core/utils/DebouncedClickListener.kt b/vector/src/main/java/im/vector/app/core/utils/DebouncedClickListener.kt index 8f96a286d9..f7c3eec112 100644 --- a/vector/src/main/java/im/vector/app/core/utils/DebouncedClickListener.kt +++ b/vector/src/main/java/im/vector/app/core/utils/DebouncedClickListener.kt @@ -15,24 +15,30 @@ */ package im.vector.app.core.utils +import android.os.SystemClock import android.view.View +import timber.log.Timber import java.util.WeakHashMap /** * Simple Debounced OnClickListener * 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() - override fun onClick(clickedView: View) { - val previousClickTimestamp = lastClickMap[clickedView] - val currentTimestamp = System.currentTimeMillis() + override fun onClick(v: View) { + val previousClickTimestamp = lastClickMap[v] ?: 0 + val currentTimestamp = SystemClock.elapsedRealtime() + lastClickMap[v] = currentTimestamp - lastClickMap[clickedView] = currentTimestamp - - if (previousClickTimestamp == null || currentTimestamp - previousClickTimestamp.toLong() > minimumInterval) { - original.onClick(clickedView) + if (currentTimestamp > previousClickTimestamp + minimumInterval) { + original.onClick(v) + } else { + Timber.v("Debounced click!") } } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index 28ea5234a7..3d70615abf 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -16,14 +16,15 @@ package im.vector.app.features.autocomplete -import android.view.View import android.widget.ImageView import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem @@ -34,11 +35,11 @@ abstract class AutocompleteMatrixItem : VectorEpoxyModel - host.listener?.onItemClick(command) - } + clickListener { host.listener?.onItemClick(command) } } } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandItem.kt index 0f24b866bf..b978612685 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandItem.kt @@ -16,13 +16,14 @@ package im.vector.app.features.autocomplete.command -import android.view.View import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick @EpoxyModelClass(layout = R.layout.item_autocomplete_command) abstract class AutocompleteCommandItem : VectorEpoxyModel() { @@ -36,13 +37,12 @@ abstract class AutocompleteCommandItem : VectorEpoxyModel - host.listener?.onItemClick(groupSummary) - } + clickListener { host.listener?.onItemClick(groupSummary) } } } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 66c6705d14..9b4bd78504 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -40,9 +40,7 @@ class AutocompleteMemberController @Inject constructor() : TypedEpoxyController< id(user.userId) matrixItem(user.toMatrixItem()) avatarRenderer(host.avatarRenderer) - clickListener { _ -> - host.listener?.onItemClick(user) - } + clickListener { host.listener?.onItemClick(user) } } } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt index 309c194272..cdc30938e7 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt @@ -39,9 +39,7 @@ class AutocompleteRoomController @Inject constructor(private val avatarRenderer: matrixItem(roomSummary.toMatrixItem()) subName(roomSummary.canonicalAlias) avatarRenderer(host.avatarRenderer) - clickListener { _ -> - host.listener?.onItemClick(roomSummary) - } + clickListener { host.listener?.onItemClick(roomSummary) } } } } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactDetailItem.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactDetailItem.kt index aba530b2fb..fbf404b74d 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactDetailItem.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactDetailItem.kt @@ -31,7 +31,9 @@ abstract class ContactDetailItem : VectorEpoxyModel() @EpoxyAttribute lateinit var threePid: String @EpoxyAttribute var matrixId: String? = null - @EpoxyAttribute var clickListener: ClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt index 5da66661fd..05a2bf641b 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt @@ -95,35 +95,35 @@ class ContactsBookController @Inject constructor( avatarRenderer(host.avatarRenderer) } mappedContact.emails - .forEachIndexed { index, it -> - if (onlyBoundContacts && it.matrixId == null) return@forEachIndexed + .forEachIndexed { index, email -> + if (onlyBoundContacts && email.matrixId == null) return@forEachIndexed contactDetailItem { - id("${mappedContact.id}-e-$index-${it.email}") - threePid(it.email) - matrixId(it.matrixId) + id("${mappedContact.id}-e-$index-${email.email}") + threePid(email.email) + matrixId(email.matrixId) clickListener { - if (it.matrixId != null) { - host.callback?.onMatrixIdClick(it.matrixId) + if (email.matrixId != null) { + host.callback?.onMatrixIdClick(email.matrixId) } else { - host.callback?.onThreePidClick(ThreePid.Email(it.email)) + host.callback?.onThreePidClick(ThreePid.Email(email.email)) } } } } mappedContact.msisdns - .forEachIndexed { index, it -> - if (onlyBoundContacts && it.matrixId == null) return@forEachIndexed + .forEachIndexed { index, msisdn -> + if (onlyBoundContacts && msisdn.matrixId == null) return@forEachIndexed contactDetailItem { - id("${mappedContact.id}-m-$index-${it.phoneNumber}") - threePid(it.phoneNumber) - matrixId(it.matrixId) + id("${mappedContact.id}-m-$index-${msisdn.phoneNumber}") + threePid(msisdn.phoneNumber) + matrixId(msisdn.matrixId) clickListener { - if (it.matrixId != null) { - host.callback?.onMatrixIdClick(it.matrixId) + if (msisdn.matrixId != null) { + host.callback?.onMatrixIdClick(msisdn.matrixId) } else { - host.callback?.onThreePidClick(ThreePid.Msisdn(it.phoneNumber)) + host.callback?.onThreePidClick(ThreePid.Msisdn(msisdn.phoneNumber)) } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingFooterItem.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingFooterItem.kt index 0489f18abe..69551cac93 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingFooterItem.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingFooterItem.kt @@ -16,14 +16,15 @@ package im.vector.app.features.crypto.keysbackup.settings -import android.view.View import android.widget.Button import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide @EpoxyModelClass(layout = R.layout.item_keys_backup_settings_button_footer) @@ -32,22 +33,22 @@ abstract class KeysBackupSettingFooterItem : VectorEpoxyModel Unit + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + lateinit var listener: ClickListener override fun bind(holder: Holder) { super.bind(holder) - holder.view.setOnClickListener { - listener.invoke() - } - + holder.view.onClick(listener) holder.title.text = title holder.title.setTextColor(titleColor) diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt index ed0a58231e..ed52deeade 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt @@ -16,7 +16,6 @@ package im.vector.app.features.devtools -import android.view.View import com.airbnb.epoxy.EpoxyController import im.vector.app.R import im.vector.app.core.resources.StringProvider @@ -38,23 +37,23 @@ class RoomDevToolRootController @Inject constructor( genericButtonItem { id("explore") text(host.stringProvider.getString(R.string.dev_tools_explore_room_state)) - buttonClickAction(View.OnClickListener { + buttonClickAction { host.interactionListener?.processAction(RoomDevToolAction.ExploreRoomState) - }) + } } genericButtonItem { id("send") text(host.stringProvider.getString(R.string.dev_tools_send_custom_event)) - buttonClickAction(View.OnClickListener { + buttonClickAction { host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false)) - }) + } } genericButtonItem { id("send_state") text(host.stringProvider.getString(R.string.dev_tools_send_state_event)) - buttonClickAction(View.OnClickListener { + buttonClickAction { host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true)) - }) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt index 25cd2f129f..324377bc57 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt @@ -21,7 +21,6 @@ import im.vector.app.R import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider -import im.vector.app.core.ui.list.GenericItem import im.vector.app.core.ui.list.genericItem import me.gujun.android.span.span import org.json.JSONObject @@ -51,11 +50,9 @@ class RoomStateListController @Inject constructor( id(entry.key) title(entry.key) description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size)) - itemClickAction(GenericItem.Action("view").apply { - perform = Runnable { - host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key)) - } - }) + itemClickAction { + host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key)) + } } } } @@ -93,11 +90,9 @@ class RoomStateListController @Inject constructor( } }) description(contentJson) - itemClickAction(GenericItem.Action("view").apply { - perform = Runnable { - host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent)) - } - }) + itemClickAction { + host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent)) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt index 25cb3ce8dd..a35329d6aa 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.discovery -import android.view.View import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Async import com.airbnb.mvrx.Fail @@ -125,7 +124,7 @@ class DiscoverySettingsController @Inject constructor( id("idServerFooter") helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer)) showCompoundDrawable(true) - itemClickListener(View.OnClickListener { host.listener?.openIdentityServerTerms() }) + itemClickListener { host.listener?.openIdentityServerTerms() } } settingsButtonItem { id("seeTerms") diff --git a/vector/src/main/java/im/vector/app/features/discovery/SettingsButtonItem.kt b/vector/src/main/java/im/vector/app/features/discovery/SettingsButtonItem.kt index 38f2343316..ed8ab8f768 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/SettingsButtonItem.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/SettingsButtonItem.kt @@ -44,7 +44,7 @@ abstract class SettingsButtonItem : EpoxyModelWithHolder( @StringRes var helperTextResId: Int? = null - @EpoxyAttribute - var itemClickListener: View.OnClickListener? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null @EpoxyAttribute @DrawableRes @@ -55,7 +56,7 @@ abstract class SettingsInfoItem : EpoxyModelWithHolder( holder.text.setTextOrHide(helperText) } - holder.view.setOnClickListener(itemClickListener) + holder.view.onClick(itemClickListener) if (showCompoundDrawable) { holder.text.setCompoundDrawablesWithIntrinsicBounds(compoundDrawable, 0, 0, 0) diff --git a/vector/src/main/java/im/vector/app/features/discovery/SettingsItem.kt b/vector/src/main/java/im/vector/app/features/discovery/SettingsItem.kt index 3471a3ab56..9726e63d39 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/SettingsItem.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/SettingsItem.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.discovery -import android.view.View import android.widget.TextView import androidx.annotation.StringRes import androidx.core.view.isVisible @@ -24,7 +23,9 @@ import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelWithHolder import com.google.android.material.switchmaterial.SwitchMaterial 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.onClick import im.vector.app.core.extensions.setTextOrHide @EpoxyModelClass(layout = R.layout.item_settings_simple_item) @@ -44,8 +45,8 @@ abstract class SettingsItem : EpoxyModelWithHolder() { @EpoxyAttribute var description: CharSequence? = null - @EpoxyAttribute - var itemClickListener: View.OnClickListener? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -63,7 +64,7 @@ abstract class SettingsItem : EpoxyModelWithHolder() { holder.switchButton.isVisible = false - holder.view.setOnClickListener(itemClickListener) + holder.view.onClick(itemClickListener) } class Holder : VectorEpoxyHolder() { diff --git a/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt b/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt index 9f64a68d4f..ecf762144a 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt @@ -78,7 +78,7 @@ abstract class SettingsTextButtonSingleLineItem : EpoxyModelWithHolder Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -42,7 +44,7 @@ abstract class FormAdvancedToggleItem : VectorEpoxyModel() { @EpoxyAttribute var endIconMode: Int? = null - // FIXME restore EpoxyAttribute.Option.DoNotHash and fix that properly - @EpoxyAttribute - var onTextChange: ((String) -> Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onTextChange: TextListener? = null - @EpoxyAttribute + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var editorActionListener: TextView.OnEditorActionListener? = null private val onTextChangeListener = object : SimpleTextWatcher() { @@ -88,7 +89,7 @@ abstract class FormEditTextItem : VectorEpoxyModel() { holder.textInputEditText.isSingleLine = singleLine holder.textInputEditText.imeOptions = imeOptions ?: EditorInfo.IME_ACTION_NONE - holder.textInputEditText.addTextChangedListener(onTextChangeListener) + holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener) holder.textInputEditText.setOnEditorActionListener(editorActionListener) holder.bottomSeparator.isVisible = showBottomSeparator } diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextWithButtonItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextWithButtonItem.kt index 6cf862b10b..1578bb09e2 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextWithButtonItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextWithButtonItem.kt @@ -17,15 +17,18 @@ package im.vector.app.features.form import android.text.Editable -import android.view.View import androidx.appcompat.widget.AppCompatButton import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout 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.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.platform.SimpleTextWatcher @@ -44,11 +47,11 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onTextChange: TextListener? = null - @EpoxyAttribute - var onButtonClicked: ((View) -> Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onButtonClicked: ClickListener? = null private val onTextChangeListener = object : SimpleTextWatcher() { override fun afterTextChanged(s: Editable) { @@ -65,11 +68,10 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel Unit)? = null + var onTextChange: TextListener? = null private val onTextChangeListener = object : SimpleTextWatcher() { override fun afterTextChanged(s: Editable) { @@ -80,7 +82,7 @@ abstract class FormMultiLineEditTextItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer @EpoxyAttribute lateinit var matrixItem: MatrixItem @EpoxyAttribute var selected: Boolean = false - @EpoxyAttribute var listener: (() -> Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) - holder.rootView.setOnClickListener { listener?.invoke() } + holder.rootView.onClick(listener) holder.groupNameView.text = matrixItem.displayName holder.rootView.isChecked = selected avatarRenderer.render(matrixItem, holder.avatarImageView) diff --git a/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt b/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt index ddda38aa9c..cb291a88ca 100644 --- a/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt @@ -26,8 +26,10 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.core.platform.CheckableConstraintLayout import im.vector.app.features.home.room.list.UnreadCounterBadgeView import im.vector.app.features.themes.ThemeUtils @@ -36,7 +38,7 @@ import im.vector.app.features.themes.ThemeUtils abstract class HomeSpaceSummaryItem : VectorEpoxyModel() { @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 showSeparator: Boolean = false @@ -47,7 +49,7 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel breadcrumbsItem { - id(it.roomId) - hasTypingUsers(it.typingUsers.isNotEmpty()) + id(roomSummary.roomId) + hasTypingUsers(roomSummary.typingUsers.isNotEmpty()) avatarRenderer(host.avatarRenderer) - matrixItem(it.toMatrixItem()) - unreadNotificationCount(it.notificationCount) - showHighlighted(it.highlightCount > 0) - hasUnreadMessage(it.hasUnreadMessages) - hasDraft(it.userDrafts.isNotEmpty()) - itemClickListener( - DebouncedClickListener({ _ -> - host.listener?.onBreadcrumbClicked(it.roomId) - }) - ) + matrixItem(roomSummary.toMatrixItem()) + unreadNotificationCount(roomSummary.notificationCount) + showHighlighted(roomSummary.highlightCount > 0) + hasUnreadMessage(roomSummary.hasUnreadMessages) + hasDraft(roomSummary.userDrafts.isNotEmpty()) + itemClickListener { + host.listener?.onBreadcrumbClicked(roomSummary.roomId) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt index f39b7b6d0a..fd912a4953 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt @@ -23,8 +23,10 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.list.UnreadCounterBadgeView import org.matrix.android.sdk.api.util.MatrixItem @@ -39,11 +41,11 @@ abstract class BreadcrumbsItem : VectorEpoxyModel() { @EpoxyAttribute var showHighlighted: Boolean = false @EpoxyAttribute var hasUnreadMessage: 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) { super.bind(holder) - holder.rootView.setOnClickListener(itemClickListener) + holder.rootView.onClick(itemClickListener) holder.unreadIndentIndicator.isVisible = hasUnreadMessage avatarRenderer.render(matrixItem, holder.avatarImageView) holder.avatarImageView.contentDescription = matrixItem.getBestName() @@ -52,11 +54,6 @@ abstract class BreadcrumbsItem : VectorEpoxyModel() { holder.typingIndicator.isVisible = hasTypingUsers } - override fun unbind(holder: Holder) { - holder.rootView.setOnClickListener(null) - super.unbind(holder) - } - class Holder : VectorEpoxyHolder() { val unreadCounterBadgeView by bind(R.id.breadcrumbsUnreadCounterBadgeView) val unreadIndentIndicator by bind(R.id.breadcrumbsUnreadIndicator) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt index b95239df44..c097b9adb5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt @@ -23,7 +23,9 @@ import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelWithHolder 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.onClick import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem @@ -33,7 +35,7 @@ abstract class DisplayReadReceiptItem : EpoxyModelWithHolder Unit)? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var userClicked: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -45,7 +47,7 @@ abstract class DisplayReadReceiptItem : EpoxyModelWithHolder) { - readReceipts.forEach { - val timestamp = dateFormatter.format(it.timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME) + readReceipts.forEach { readReceiptData -> + val timestamp = dateFormatter.format(readReceiptData.timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME) DisplayReadReceiptItem_() - .id(it.userId) - .matrixItem(it.toMatrixItem()) + .id(readReceiptData.userId) + .matrixItem(readReceiptData.toMatrixItem()) .avatarRenderer(avatarRender) .timestamp(timestamp) - .userClicked { listener?.didSelectUser(it.userId) } - .addIf(session.myUserId != it.userId, this) + .userClicked { listener?.didSelectUser(readReceiptData.userId) } + .addIf(session.myUserId != readReceiptData.userId, this) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt index 74bd168d09..1debf32104 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt @@ -29,7 +29,7 @@ import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.epoxy.noResultItem 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 org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Content @@ -111,7 +111,7 @@ class SearchResultController @Inject constructor( timeInMillis = eventAndSender.event.originServerTs ?: System.currentTimeMillis() } if (lastDate?.get(Calendar.DAY_OF_YEAR) != eventDate.get(Calendar.DAY_OF_YEAR)) { - GenericItemHeader_() + GenericHeaderItem_() .id(eventDate.hashCode()) .text(dateFormatter.format(eventDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER)) .let { result.add(it) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt index a3e5983c3a..14ea94ffd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt @@ -36,7 +36,7 @@ abstract class SearchResultItem : VectorEpoxyModel() { @EpoxyAttribute var formattedDate: String? = null @EpoxyAttribute lateinit var spannable: CharSequence @EpoxyAttribute var sender: MatrixItem? = null - @EpoxyAttribute var listener: ClickListener? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null override fun bind(holder: Holder) { super.bind(holder) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index e7c48739fc..303850c33f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.home.room.detail.timeline.action -import android.view.View import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Success import im.vector.app.EmojiCompatFontProvider @@ -107,7 +106,7 @@ class MessageActionsEpoxyController @Inject constructor( } when (state.informationData.e2eDecoration) { - E2EDecoration.WARN_IN_CLEAR -> { + E2EDecoration.WARN_IN_CLEAR -> { bottomSheetSendStateItem { id("e2e_clear") showProgress(false) @@ -169,7 +168,7 @@ class MessageActionsEpoxyController @Inject constructor( textRes(action.titleRes) showExpand(action is EventSharedAction.ReportContent) expanded(state.expendedReportContentMenu) - listener(View.OnClickListener { host.listener?.didSelectMenuAction(action) }) + listener { host.listener?.didSelectMenuAction(action) } destructive(action.destructive) } @@ -185,7 +184,7 @@ class MessageActionsEpoxyController @Inject constructor( subMenuItem(true) iconRes(actionReport.iconResId) textRes(actionReport.titleRes) - listener(View.OnClickListener { host.listener?.didSelectMenuAction(actionReport) }) + listener { host.listener?.didSelectMenuAction(actionReport) } } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt index c3c53084ed..b526e0e058 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt @@ -26,8 +26,8 @@ import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider 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.genericItemHeader import im.vector.app.core.ui.list.genericLoaderItem import im.vector.app.features.html.EventHtmlRenderer 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)) { // need to display header with day - genericItemHeader { + genericHeaderItem { id(evDate.hashCode()) text(host.dateFormatter.format(evDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER)) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 7b9601ad33..c2ab7addd0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -29,7 +29,6 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.files.LocalFilesHelper import im.vector.app.core.resources.ColorProvider 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.containsOnlyEmojis 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) { mode(ImageContentRenderer.Mode.STICKER) } else { - clickListener( - DebouncedClickListener({ view -> - callback?.onImageMessageClicked(messageContent, data, view) - })) + clickListener { view -> + callback?.onImageMessageClicked(messageContent, data, view) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt index 1d015d1bca..8a74a6d207 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt @@ -16,7 +16,6 @@ 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.room.detail.timeline.TimelineEventController 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) .readReceipts(readReceiptsData) .avatarRenderer(avatarRenderer) - .clickListener(DebouncedClickListener({ _ -> + .clickListener { callback?.onReadReceiptsClicked(readReceiptsData) - })) + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt index 043fd9e896..679613d262 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt @@ -16,7 +16,6 @@ package im.vector.app.features.home.room.detail.timeline.helper 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.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController @@ -41,12 +40,12 @@ class MessageItemAttributesFactory @Inject constructor( itemLongClickListener = { view -> callback?.onEventLongClicked(informationData, messageContent, view) ?: false }, - itemClickListener = DebouncedClickListener({ view -> + itemClickListener = { view -> callback?.onEventCellClicked(informationData, messageContent, view) - }), - memberClickListener = DebouncedClickListener({ + }, + memberClickListener = { callback?.onMemberNameClicked(informationData) - }), + }, reactionPillCallback = callback, avatarCallback = callback, readReceiptsCallback = callback, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 39c04af089..080b766258 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -23,6 +23,8 @@ import android.widget.TextView import androidx.annotation.IdRes import androidx.core.view.isVisible 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.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.MessageColorProvider @@ -94,7 +96,7 @@ abstract class AbsBaseMessageItem : BaseEventItem } } - holder.view.setOnClickListener(baseAttributes.itemClickListener) + holder.view.onClick(baseAttributes.itemClickListener) holder.view.setOnLongClickListener(baseAttributes.itemLongClickListener) } @@ -124,9 +126,9 @@ abstract class AbsBaseMessageItem : BaseEventItem val avatarRenderer: AvatarRenderer val messageColorProvider: MessageColorProvider val itemLongClickListener: View.OnLongClickListener? - val itemClickListener: View.OnClickListener? + val itemClickListener: ClickListener? - // val memberClickListener: View.OnClickListener? + // val memberClickListener: ClickListener? val reactionPillCallback: TimelineEventController.ReactionPillCallback? // val avatarCallback: TimelineEventController.AvatarCallback? @@ -139,7 +141,7 @@ abstract class AbsBaseMessageItem : BaseEventItem // override val avatarRenderer: AvatarRenderer, // override val colorProvider: ColorProvider, // 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 readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null // ) : Attributes diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt index ed61abcf6e..fd5eea1b49 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -26,8 +26,9 @@ import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute 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.utils.DebouncedClickListener 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.TimelineEventController @@ -44,12 +45,17 @@ abstract class AbsMessageItem : AbsBaseMessageItem @EpoxyAttribute lateinit var attributes: Attributes - private val _avatarClickListener = DebouncedClickListener({ - attributes.avatarCallback?.onAvatarClicked(attributes.informationData) - }) - private val _memberNameClickListener = DebouncedClickListener({ - attributes.avatarCallback?.onMemberNameClicked(attributes.informationData) - }) + private val _avatarClickListener = object : ClickListener { + override fun invoke(p1: View) { + attributes.avatarCallback?.onAvatarClicked(attributes.informationData) + } + } + + private val _memberNameClickListener = object : ClickListener { + override fun invoke(p1: View) { + attributes.avatarCallback?.onMemberNameClicked(attributes.informationData) + } + } override fun bind(holder: H) { super.bind(holder) @@ -59,9 +65,9 @@ abstract class AbsMessageItem : AbsBaseMessageItem width = attributes.avatarSize } holder.avatarImageView.visibility = View.VISIBLE - holder.avatarImageView.setOnClickListener(_avatarClickListener) + holder.avatarImageView.onClick(_avatarClickListener) holder.memberNameView.visibility = View.VISIBLE - holder.memberNameView.setOnClickListener(_memberNameClickListener) + holder.memberNameView.onClick(_memberNameClickListener) holder.timeView.visibility = View.VISIBLE holder.timeView.text = attributes.informationData.time holder.memberNameView.text = attributes.informationData.memberName @@ -118,8 +124,8 @@ abstract class AbsMessageItem : AbsBaseMessageItem override val avatarRenderer: AvatarRenderer, override val messageColorProvider: MessageColorProvider, override val itemLongClickListener: View.OnLongClickListener? = null, - override val itemClickListener: View.OnClickListener? = null, - val memberClickListener: View.OnClickListener? = null, + override val itemClickListener: ClickListener? = null, + val memberClickListener: ClickListener? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, val avatarCallback: TimelineEventController.AvatarCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt index 2d40035df1..5c4edf2d62 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt @@ -28,6 +28,8 @@ import androidx.core.view.updateLayoutParams import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.setTextWithColoredPart import im.vector.app.features.home.AvatarRenderer @@ -64,11 +66,11 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem + holder.roomAvatarImageView.onClick { view -> if (shouldSetAvatar) { attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar) } else { // Note: this is no op if there is no avatar on the room attributes.callback?.onTimelineItemAction(RoomDetailAction.ShowRoomAvatarFullScreen(roomItem, view)) } - })) + } } holder.setAvatarButton.isVisible = shouldSetAvatar if (shouldSetAvatar) { - holder.setAvatarButton.setOnClickListener(DebouncedClickListener({ + holder.setAvatarButton.onClick { attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionSetAvatar) - })) + } } holder.addPeopleButton.isVisible = !isDirect if (!isDirect) { - holder.addPeopleButton.setOnClickListener(DebouncedClickListener({ + holder.addPeopleButton.onClick { attributes.callback?.onTimelineItemAction(RoomDetailAction.QuickActionInvitePeople) - })) + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt index def79e4fe6..3f6add5699 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt @@ -20,6 +20,7 @@ import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R +import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide import me.saket.bettermovementmethod.BetterLinkMovementMethod @@ -36,7 +37,7 @@ abstract class MessageBlockCodeItem : AbsMessageItem() { var iconRes: Int = 0 // @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) -// var clickListener: View.OnClickListener? = null +// var clickListener: ClickListener? = null @EpoxyAttribute var izLocalFile = false @@ -81,9 +82,9 @@ abstract class MessageFileItem : AbsMessageItem() { } // holder.view.setOnClickListener(clickListener) - holder.filenameView.setOnClickListener(attributes.itemClickListener) + holder.filenameView.onClick(attributes.itemClickListener) holder.filenameView.setOnLongClickListener(attributes.itemLongClickListener) - holder.fileImageWrapper.setOnClickListener(attributes.itemClickListener) + holder.fileImageWrapper.onClick(attributes.itemClickListener) holder.fileImageWrapper.setOnLongClickListener(attributes.itemLongClickListener) holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageImageVideoItem.kt index 2c0d1fcfbd..3ae91db97c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageImageVideoItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageImageVideoItem.kt @@ -24,6 +24,8 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.glide.GlideApp import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder @@ -42,7 +44,7 @@ abstract class MessageImageVideoItem : AbsMessageItem() as MaterialButton holder.buttonContainer.addView(materialButton, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) materialButton.text = option.label - materialButton.setOnClickListener { + materialButton.onClick { callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(relatedEventId, index, option.value ?: "$index")) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessagePollItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessagePollItem.kt index ca5c3b2dea..2178843c28 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessagePollItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessagePollItem.kt @@ -24,8 +24,9 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.utils.DebouncedClickListener import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.timeline.TimelineEventController import org.matrix.android.sdk.api.session.room.model.message.MessageOptionsContent @@ -143,14 +144,16 @@ abstract class MessagePollItem : AbsMessageItem() { override fun bindView(itemView: View) { super.bindView(itemView) val buttons = listOf(button1, button2, button3, button4, button5) - val clickListener = DebouncedClickListener({ - val optionIndex = buttons.indexOf(it) - if (optionIndex != -1 && pollId != null) { - val compatValue = if (optionIndex < optionValues?.size ?: 0) optionValues?.get(optionIndex) else null - callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(pollId!!, optionIndex, compatValue ?: "$optionIndex")) + val clickListener = object : ClickListener { + override fun invoke(p1: View) { + val optionIndex = buttons.indexOf(p1) + if (optionIndex != -1 && pollId != null) { + val compatValue = if (optionIndex < optionValues?.size ?: 0) optionValues?.get(optionIndex) else null + callback?.onTimelineItemAction(RoomDetailAction.ReplyToOptions(pollId!!, optionIndex, compatValue ?: "$optionIndex")) + } } - }) - buttons.forEach { it.setOnClickListener(clickListener) } + } + buttons.forEach { it.onClick(clickListener) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt index 86b83cbe47..c6dce5a9ce 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -24,6 +24,7 @@ import androidx.core.widget.TextViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.tools.findPillsAndProcess import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever @@ -95,7 +96,7 @@ abstract class MessageTextItem : AbsMessageItem() { holder.messageView.movementMethod = movementMethod renderSendState(holder.messageView, holder.messageView) - holder.messageView.setOnClickListener(attributes.itemClickListener) + holder.messageView.onClick(attributes.itemClickListener) holder.messageView.setOnLongClickListener(attributes.itemLongClickListener) if (canUseTextFuture) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/ReadReceiptsItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/ReadReceiptsItem.kt index b88afb0598..650c804cfa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/ReadReceiptsItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/ReadReceiptsItem.kt @@ -16,12 +16,13 @@ package im.vector.app.features.home.room.detail.timeline.item -import android.view.View import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelWithHolder 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.onClick import im.vector.app.core.ui.views.ReadReceiptsView import im.vector.app.features.home.AvatarRenderer @@ -31,7 +32,7 @@ abstract class ReadReceiptsItem : EpoxyModelWithHolder( @EpoxyAttribute lateinit var eventId: String @EpoxyAttribute lateinit var readReceipts: List @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 @@ -39,7 +40,8 @@ abstract class ReadReceiptsItem : EpoxyModelWithHolder( override fun bind(holder: Holder) { super.bind(holder) - holder.readReceiptsView.render(readReceipts, avatarRenderer, clickListener) + holder.readReceiptsView.onClick(clickListener) + holder.readReceiptsView.render(readReceipts, avatarRenderer) } override fun unbind(holder: Holder) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt index c9eb14db66..c76e2b230a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt @@ -26,6 +26,7 @@ import androidx.core.view.updateLayoutParams import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass 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.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController @@ -88,7 +89,7 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem(R.id.itemVerificationTitleTextView) val descriptionView by bind(R.id.itemVerificationDetailTextView) val buttonBar by bind(R.id.itemVerificationButtonBar) val statusTextView by bind(R.id.itemVerificationStatusText) val endGuideline by bind(R.id.messageEndGuideline) - private val declineButton by bind