Use debouncedClicks where applicable

This commit is contained in:
Benoit Marty 2021-12-06 22:10:57 +01:00
parent 8421d46cd7
commit d13c252658
26 changed files with 66 additions and 50 deletions

View File

@ -79,7 +79,7 @@ class AttachmentsPreviewFragment @Inject constructor(
applyInsets() applyInsets()
setupRecyclerViews() setupRecyclerViews()
setupToolbar(views.attachmentPreviewerToolbar) setupToolbar(views.attachmentPreviewerToolbar)
views.attachmentPreviewerSendButton.setOnClickListener { views.attachmentPreviewerSendButton.debouncedClicks {
setResultAndFinish() setResultAndFinish()
} }
} }

View File

@ -77,7 +77,7 @@ class ContactsBookFragment @Inject constructor(
} }
private fun setupConsentView() { private fun setupConsentView() {
views.phoneBookSearchForMatrixContacts.setOnClickListener { views.phoneBookSearchForMatrixContacts.debouncedClicks {
contactsBookViewModel.handle(ContactsBookAction.UserConsentRequest) contactsBookViewModel.handle(ContactsBookAction.UserConsentRequest)
} }
} }

View File

@ -58,8 +58,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() :
views.keyInputLayout.error = newValue views.keyInputLayout.error = newValue
} }
views.keysRestoreButton.setOnClickListener { onRestoreFromKey() } views.keysRestoreButton.debouncedClicks { onRestoreFromKey() }
views.keysBackupImport.setOnClickListener { onImport() } views.keysBackupImport.debouncedClicks { onImport() }
views.keyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) } views.keyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) }
} }

View File

@ -58,8 +58,8 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
return@setOnEditorActionListener false return@setOnEditorActionListener false
} }
views.helperTextWithLink.setOnClickListener { onUseRecoveryKey() } views.helperTextWithLink.debouncedClicks { onUseRecoveryKey() }
views.keysBackupRestoreWithPassphraseSubmit.setOnClickListener { onRestoreBackup() } views.keysBackupRestoreWithPassphraseSubmit.debouncedClicks { onRestoreBackup() }
views.keysBackupPassphraseEnterEdittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) } views.keysBackupPassphraseEnterEdittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) }
} }

View File

@ -52,7 +52,7 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen
views.successText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date) views.successText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date)
views.successDetailsText.isVisible = false views.successDetailsText.isVisible = false
} }
views.keysBackupSetupDoneButton.setOnClickListener { onDone() } views.keysBackupSetupDoneButton.debouncedClicks { onDone() }
} }
private fun onDone() { private fun onDone() {

View File

@ -45,8 +45,8 @@ class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment<Fr
views.keysBackupSetupStep1ManualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE views.keysBackupSetupStep1ManualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE
} }
views.keysBackupSetupStep1Button.setOnClickListener { onButtonClick() } views.keysBackupSetupStep1Button.debouncedClicks { onButtonClick() }
views.keysBackupSetupStep1ManualExportButton.setOnClickListener { onManualExportClick() } views.keysBackupSetupStep1ManualExportButton.debouncedClicks { onManualExportClick() }
} }
private fun onButtonClick() { private fun onButtonClick() {

View File

@ -128,8 +128,8 @@ class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment<Fr
} }
private fun setupViews() { private fun setupViews() {
views.keysBackupSetupStep2Button.setOnClickListener { doNext() } views.keysBackupSetupStep2Button.debouncedClicks { doNext() }
views.keysBackupSetupStep2SkipButton.setOnClickListener { skipPassphrase() } views.keysBackupSetupStep2SkipButton.debouncedClicks { skipPassphrase() }
views.keysBackupSetupStep2PassphraseEnterEdittext.doOnTextChanged { _, _, _, _ -> onPassphraseChanged() } views.keysBackupSetupStep2PassphraseEnterEdittext.doOnTextChanged { _, _, _, _ -> onPassphraseChanged() }
views.keysBackupSetupStep2PassphraseConfirmEditText.doOnTextChanged { _, _, _, _ -> onConfirmPassphraseChanged() } views.keysBackupSetupStep2PassphraseConfirmEditText.doOnTextChanged { _, _, _, _ -> onConfirmPassphraseChanged() }

View File

@ -85,9 +85,9 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
} }
private fun setupViews() { private fun setupViews() {
views.keysBackupSetupStep3FinishButton.setOnClickListener { onFinishButtonClicked() } views.keysBackupSetupStep3FinishButton.debouncedClicks { onFinishButtonClicked() }
views.keysBackupSetupStep3CopyButton.setOnClickListener { onCopyButtonClicked() } views.keysBackupSetupStep3CopyButton.debouncedClicks { onCopyButtonClicked() }
views.keysBackupSetupStep3RecoveryKeyText.setOnClickListener { onRecoveryKeyClicked() } views.keysBackupSetupStep3RecoveryKeyText.debouncedClicks { onRecoveryKeyClicked() }
} }
private fun onFinishButtonClicked() { private fun onFinishButtonClicked() {
@ -127,7 +127,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
} }
} }
dialog.findViewById<View>(R.id.keys_backup_setup_save)?.setOnClickListener { dialog.findViewById<View>(R.id.keys_backup_setup_save)?.debouncedClicks {
val userId = viewModel.userId val userId = viewModel.userId
val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date()) val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
selectTxtFileToWrite( selectTxtFileToWrite(
@ -139,7 +139,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<Fr
dialog.dismiss() dialog.dismiss()
} }
dialog.findViewById<View>(R.id.keys_backup_setup_share)?.setOnClickListener { dialog.findViewById<View>(R.id.keys_backup_setup_share)?.debouncedClicks {
startSharePlainTextIntent( startSharePlainTextIntent(
fragment = this, fragment = this,
activityResultLauncher = null, activityResultLauncher = null,

View File

@ -898,7 +898,7 @@ class RoomDetailFragment @Inject constructor(
} }
private fun setupJumpToReadMarkerView() { private fun setupJumpToReadMarkerView() {
views.jumpToReadMarkerView.setOnClickListener { views.jumpToReadMarkerView.debouncedClicks {
onJumpToReadMarkerClicked() onJumpToReadMarkerClicked()
} }
views.jumpToReadMarkerView.setOnCloseIconClickListener { views.jumpToReadMarkerView.setOnCloseIconClickListener {
@ -954,7 +954,7 @@ class RoomDetailFragment @Inject constructor(
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
// We use a custom layout for this menu item, so we need to set a ClickListener // We use a custom layout for this menu item, so we need to set a ClickListener
menu.findItem(R.id.open_matrix_apps)?.let { menuItem -> menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
menuItem.actionView.setOnClickListener { menuItem.actionView.debouncedClicks {
onOptionsItemSelected(menuItem) onOptionsItemSelected(menuItem)
} }
} }
@ -1463,7 +1463,7 @@ class RoomDetailFragment @Inject constructor(
callback = this@RoomDetailFragment callback = this@RoomDetailFragment
isVisible = true isVisible = true
render(inviter, VectorInviteView.Mode.LARGE, mainState.changeMembershipState) render(inviter, VectorInviteView.Mode.LARGE, mainState.changeMembershipState)
setOnClickListener { } setOnClickListener(null)
} }
Unit Unit
} else if (mainState.asyncInviter.complete) { } else if (mainState.asyncInviter.complete) {

View File

@ -81,7 +81,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment<FragmentLog
} }
private fun setupForgottenPasswordButton() { private fun setupForgottenPasswordButton() {
views.forgetPasswordButton.setOnClickListener { forgetPasswordClicked() } views.forgetPasswordButton.debouncedClicks { forgetPasswordClicked() }
} }
private fun setupAutoFill(state: LoginViewState) { private fun setupAutoFill(state: LoginViewState) {
@ -226,7 +226,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment<FragmentLog
} }
private fun setupSubmitButton() { private fun setupSubmitButton() {
views.loginSubmit.setOnClickListener { submit() } views.loginSubmit.debouncedClicks { submit() }
combine( combine(
views.loginField.textChanges().map { it.trim().isNotEmpty() }, views.loginField.textChanges().map { it.trim().isNotEmpty() },
views.passwordField.textChanges().map { it.isNotEmpty() } views.passwordField.textChanges().map { it.isNotEmpty() }

View File

@ -78,8 +78,8 @@ class LoginGenericTextInputFormFragment @Inject constructor() : AbstractLoginFra
} }
private fun setupViews() { private fun setupViews() {
views.loginGenericTextInputFormOtherButton.setOnClickListener { onOtherButtonClicked() } views.loginGenericTextInputFormOtherButton.debouncedClicks { onOtherButtonClicked() }
views.loginGenericTextInputFormSubmit.setOnClickListener { submit() } views.loginGenericTextInputFormSubmit.debouncedClicks { submit() }
} }
private fun setupAutoFill() { private fun setupAutoFill() {

View File

@ -61,7 +61,7 @@ class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment<F
} }
private fun setupSubmitButton() { private fun setupSubmitButton() {
views.resetPasswordSubmit.setOnClickListener { submit() } views.resetPasswordSubmit.debouncedClicks { submit() }
combine( combine(
views.resetPasswordEmail.textChanges().map { it.isEmail() }, views.resetPasswordEmail.textChanges().map { it.isEmail() },
views.passwordField.textChanges().map { it.isNotEmpty() } views.passwordField.textChanges().map { it.isNotEmpty() }

View File

@ -40,7 +40,7 @@ class LoginResetPasswordMailConfirmationFragment @Inject constructor() : Abstrac
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
views.resetPasswordMailConfirmationSubmit.setOnClickListener { submit() } views.resetPasswordMailConfirmationSubmit.debouncedClicks { submit() }
} }
private fun setupUi(state: LoginViewState) { private fun setupUi(state: LoginViewState) {

View File

@ -35,7 +35,7 @@ class LoginResetPasswordSuccessFragment @Inject constructor() : AbstractLoginFra
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
views.resetPasswordSuccessSubmit.setOnClickListener { submit() } views.resetPasswordSuccessSubmit.debouncedClicks { submit() }
} }
private fun submit() { private fun submit() {

View File

@ -43,11 +43,11 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment
} }
private fun initViews() { private fun initViews() {
views.loginServerChoiceEmsLearnMore.setOnClickListener { learnMore() } views.loginServerChoiceEmsLearnMore.debouncedClicks { learnMore() }
views.loginServerChoiceMatrixOrg.setOnClickListener { selectMatrixOrg() } views.loginServerChoiceMatrixOrg.debouncedClicks { selectMatrixOrg() }
views.loginServerChoiceEms.setOnClickListener { selectEMS() } views.loginServerChoiceEms.debouncedClicks { selectEMS() }
views.loginServerChoiceOther.setOnClickListener { selectOther() } views.loginServerChoiceOther.debouncedClicks { selectOther() }
views.loginServerIKnowMyIdSubmit.setOnClickListener { loginWithMatrixId() } views.loginServerIKnowMyIdSubmit.debouncedClicks { loginWithMatrixId() }
} }
private fun updateSelectedChoice(state: LoginViewState) { private fun updateSelectedChoice(state: LoginViewState) {

View File

@ -57,9 +57,9 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment<F
} }
private fun setupViews() { private fun setupViews() {
views.loginServerUrlFormLearnMore.setOnClickListener { learnMore() } views.loginServerUrlFormLearnMore.debouncedClicks { learnMore() }
views.loginServerUrlFormClearHistory.setOnClickListener { clearHistory() } views.loginServerUrlFormClearHistory.debouncedClicks { clearHistory() }
views.loginServerUrlFormSubmit.setOnClickListener { submit() } views.loginServerUrlFormSubmit.debouncedClicks { submit() }
} }
private fun setupHomeServerField() { private fun setupHomeServerField() {

View File

@ -43,8 +43,8 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLogi
} }
private fun setupViews() { private fun setupViews() {
views.loginSignupSigninSubmit.setOnClickListener { submit() } views.loginSignupSigninSubmit.debouncedClicks { submit() }
views.loginSignupSigninSignIn.setOnClickListener { signIn() } views.loginSignupSigninSignIn.debouncedClicks { signIn() }
} }
private fun setupUi(state: LoginViewState) { private fun setupUi(state: LoginViewState) {

View File

@ -73,7 +73,7 @@ class LoginTermsFragment @Inject constructor(
} }
private fun setupViews() { private fun setupViews() {
views.loginTermsSubmit.setOnClickListener { submit() } views.loginTermsSubmit.debouncedClicks { submit() }
} }
override fun onDestroyView() { override fun onDestroyView() {

View File

@ -85,11 +85,11 @@ class AccountCreatedFragment @Inject constructor(
} }
private fun setupClickListener() { private fun setupClickListener() {
views.loginAccountCreatedMessage.setOnClickListener { views.loginAccountCreatedMessage.debouncedClicks {
// Update display name // Update display name
displayDialog() displayDialog()
} }
views.loginAccountCreatedAvatar.setOnClickListener { views.loginAccountCreatedAvatar.debouncedClicks {
galleryOrCameraDialogHelper.show() galleryOrCameraDialogHelper.show()
} }
} }
@ -120,8 +120,8 @@ class AccountCreatedFragment @Inject constructor(
} }
private fun setupSubmitButton() { private fun setupSubmitButton() {
views.loginAccountCreatedLater.setOnClickListener { terminate() } views.loginAccountCreatedLater.debouncedClicks { terminate() }
views.loginAccountCreatedDone.setOnClickListener { terminate() } views.loginAccountCreatedDone.debouncedClicks { terminate() }
} }
private fun terminate() { private fun terminate() {

View File

@ -232,10 +232,10 @@ class RoomMemberProfileFragment @Inject constructor(
headerViews.memberProfileDecorationImageView.isVisible = false headerViews.memberProfileDecorationImageView.isVisible = false
} }
headerViews.memberProfileAvatarView.setOnClickListener { view -> headerViews.memberProfileAvatarView.debouncedClicks { view ->
onAvatarClicked(view, userMatrixItem) onAvatarClicked(view, userMatrixItem)
} }
views.matrixProfileToolbarAvatarImageView.setOnClickListener { view -> views.matrixProfileToolbarAvatarImageView.debouncedClicks { view ->
onAvatarClicked(view, userMatrixItem) onAvatarClicked(view, userMatrixItem)
} }
} }

View File

@ -146,12 +146,12 @@ class RoomProfileFragment @Inject constructor(
headerViews.roomProfileNameView, headerViews.roomProfileNameView,
views.matrixProfileToolbarTitleView views.matrixProfileToolbarTitleView
).forEach { ).forEach {
it.setOnClickListener { it.debouncedClicks {
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomSettings) roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomSettings)
} }
} }
// Shortcut to room alias // Shortcut to room alias
headerViews.roomProfileAliasView.setOnClickListener { headerViews.roomProfileAliasView.debouncedClicks {
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomAliasesSettings) roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomAliasesSettings)
} }
// Open Avatar // Open Avatar
@ -159,7 +159,7 @@ class RoomProfileFragment @Inject constructor(
headerViews.roomProfileAvatarView, headerViews.roomProfileAvatarView,
views.matrixProfileToolbarAvatarImageView views.matrixProfileToolbarAvatarImageView
).forEach { view -> ).forEach { view ->
view.setOnClickListener { onAvatarClicked(view) } view.debouncedClicks { onAvatarClicked(view) }
} }
} }

View File

@ -20,14 +20,19 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.flow.throttleFirst
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import reactivecircus.flowbinding.android.view.clicks
import timber.log.Timber import timber.log.Timber
abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat() { abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat() {
@ -42,6 +47,17 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat() {
protected lateinit var session: Session protected lateinit var session: Session
protected lateinit var errorFormatter: ErrorFormatter protected lateinit var errorFormatter: ErrorFormatter
/* ==========================================================================================
* Views
* ========================================================================================== */
protected fun View.debouncedClicks(onClicked: () -> Unit) {
clicks()
.throttleFirst(300)
.onEach { onClicked() }
.launchIn(viewLifecycleOwner.lifecycleScope)
}
abstract val preferenceXmlRes: Int abstract val preferenceXmlRes: Int
@CallSuper @CallSuper

View File

@ -418,7 +418,7 @@ class VectorSettingsGeneralFragment @Inject constructor(
} }
} }
updateButton.setOnClickListener { updateButton.debouncedClicks {
// Hide passwords during processing // Hide passwords during processing
views.changePasswordOldPwdText.hidePassword() views.changePasswordOldPwdText.hidePassword()
views.changePasswordNewPwdText.hidePassword() views.changePasswordNewPwdText.hidePassword()

View File

@ -197,7 +197,7 @@ class VectorSettingsPreferencesFragment @Inject constructor(
.forEachIndexed { i, v -> .forEachIndexed { i, v ->
v.isChecked = i == index v.isChecked = i == index
v.setOnClickListener { v.debouncedClicks {
dialog.dismiss() dialog.dismiss()
FontScale.updateFontScale(activity, i) FontScale.updateFontScale(activity, i)
vectorConfiguration.applyToApplicationContext() vectorConfiguration.applyToApplicationContext()

View File

@ -446,7 +446,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
val importDialog = builder.show() val importDialog = builder.show()
views.dialogE2eKeysImportButton.setOnClickListener { views.dialogE2eKeysImportButton.debouncedClicks {
val password = views.dialogE2eKeysPassphraseEditText.text.toString() val password = views.dialogE2eKeysPassphraseEditText.text.toString()
displayLoadingView() displayLoadingView()

View File

@ -118,7 +118,7 @@ class IncomingShareFragment @Inject constructor(
return true return true
} }
}) })
views.sendShareButton.setOnClickListener { views.sendShareButton.debouncedClicks {
handleSendShare() handleSendShare()
} }
} }