From 89a52408b24e2b60f6930f15f651580b718a2627 Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Mon, 11 Mar 2024 13:41:28 +0200
Subject: [PATCH] Add multiple emails support on validate emails screen

---
 .../validate_email/ValidateEmailDataSource.kt |  7 +-
 .../validate_email/ValidateEmailFragment.kt   | 80 +++++++++++++------
 .../validate_email/ValidateEmailViewModel.kt  |  2 +-
 .../res/layout/fragment_validate_email.xml    | 49 ++++++++----
 4 files changed, 92 insertions(+), 46 deletions(-)

diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
index f2f052203..fd32daa65 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailDataSource.kt
@@ -38,9 +38,10 @@ class ValidateEmailDataSource @Inject constructor() {
         return currentStageKey == LOGIN_EMAIL_REQUEST_TOKEN_TYPE || currentStageKey == LOGIN_EMAIL_SUBMIT_TOKEN_TYPE
     }
 
-    fun getPrefilledEmail(): String? =
-        if (isLogin()) ((uiaDataSource.currentStage as? Stage.Other)?.params?.get(EMAILS_LIST_KEY) as? List<*>)?.firstOrNull()
-            ?.toString() else null
+    fun getUsersEmails(): List<String> =
+        if (isLogin()) ((uiaDataSource.currentStage as? Stage.Other)?.params?.get(EMAILS_LIST_KEY) as? List<*>)?.map { it.toString() }
+            ?: emptyList()
+        else emptyList()
 
     fun shouldShowSubscribeToEmail(): Boolean =
         (uiaDataSource.currentStage as? Stage.Other)?.params?.get(OFFER_LIST_SUBSCRIPTION_KEY) as? Boolean
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
index 96f7ff493..6e899ed13 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailFragment.kt
@@ -2,6 +2,7 @@ package org.futo.circles.auth.feature.uia.stages.validate_email
 
 import android.os.Bundle
 import android.view.View
+import android.widget.ArrayAdapter
 import androidx.core.view.isVisible
 import androidx.core.widget.doAfterTextChanged
 import androidx.fragment.app.Fragment
@@ -10,6 +11,8 @@ import by.kirich1409.viewbindingdelegate.viewBinding
 import dagger.hilt.android.AndroidEntryPoint
 import org.futo.circles.auth.R
 import org.futo.circles.auth.databinding.FragmentValidateEmailBinding
+import org.futo.circles.auth.feature.uia.UIADataSource
+import org.futo.circles.auth.feature.uia.UIADataSourceProvider
 import org.futo.circles.core.base.fragment.HasLoadingState
 import org.futo.circles.core.base.fragment.ParentBackPressOwnerFragment
 import org.futo.circles.core.extensions.getText
@@ -30,6 +33,16 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
     private val binding by viewBinding(FragmentValidateEmailBinding::bind)
     private val viewModel by viewModels<ValidateEmailViewModel>()
 
+    private val emailsAdapter by lazy {
+        ArrayAdapter(
+            requireContext(),
+            org.futo.circles.core.R.layout.view_spinner_item,
+            mutableListOf<String>()
+        ).apply {
+            setDropDownViewResource(org.futo.circles.core.R.layout.view_spinner_item)
+        }
+    }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         setupViews()
@@ -38,33 +51,44 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
 
     private fun setupViews() {
         with(binding) {
-            setAlwaysDisabledViews(listOf(binding.etEmail))
-            tilEmail.editText?.doAfterTextChanged {
-                it?.let { btnSendCode.isEnabled = it.isValidEmail() }
-            }
-            tilValidationCode.editText?.doAfterTextChanged {
-                it?.let { btnValidate.isEnabled = it.isNotEmpty() }
-            }
-            tilEmail.setEndIconOnClickListener {
-                showDialog(
-                    R.string.email,
-                    R.string.email_usage_explanation
-                )
+            tilEmail.apply {
+                setIsVisible(isEnrollMode())
+                editText?.doAfterTextChanged {
+                    it?.let { btnSendCode.isEnabled = it.isValidEmail() }
+                }
+                setEndIconOnClickListener {
+                    showDialog(
+                        R.string.email,
+                        R.string.email_usage_explanation
+                    )
+                }
             }
-            tilValidationCode.setEndIconOnClickListener {
-                showDialog(
-                    R.string.validation_code,
-                    R.string.validation_code_explanation
-                )
+            tilValidationCode.apply {
+                editText?.doAfterTextChanged {
+                    it?.let { btnValidate.isEnabled = it.isNotEmpty() }
+                }
+                setEndIconOnClickListener {
+                    showDialog(
+                        R.string.validation_code,
+                        R.string.validation_code_explanation
+                    )
+                }
             }
             btnSendCode.setOnClickListener {
                 startLoading(btnSendCode)
-                viewModel.sendCode(getEmailInput(), cbEmailUpdates.isChecked && cbEmailUpdates.isVisible)
+                viewModel.sendCode(
+                    getEmailInput(),
+                    cbEmailUpdates.isChecked && cbEmailUpdates.isVisible
+                )
             }
             btnValidate.setOnClickListener {
                 startLoading(btnValidate)
                 viewModel.validateEmail(tilValidationCode.getText())
             }
+            spEmail.apply {
+                setIsVisible(!isEnrollMode())
+                adapter = emailsAdapter
+            }
         }
     }
 
@@ -77,17 +101,23 @@ class ValidateEmailFragment : ParentBackPressOwnerFragment(R.layout.fragment_val
         viewModel.showSubscribeCheckLiveData.observeData(this) {
             binding.cbEmailUpdates.setIsVisible(it)
         }
-        viewModel.usersEmailLiveData.observeData(this) {email->
-            email?.let {
-                binding.etEmail.apply {
-                    setText(it)
-                    isEnabled = false
-                }
+        viewModel.usersEmailLiveData.observeData(this) { emails ->
+            emailsAdapter.apply {
+                addAll(emails)
+                notifyDataSetChanged()
+                binding.btnSendCode.isEnabled = emails.isNotEmpty()
             }
         }
     }
 
-    private fun getEmailInput(): String = binding.tilEmail.getText()
+    private fun getEmailInput(): String = if (isEnrollMode()) binding.tilEmail.getText() else
+        emailsAdapter.getItem(binding.spEmail.selectedItemPosition) ?: ""
+
+    private fun isEnrollMode(): Boolean {
+        val currentStageKey = UIADataSourceProvider.getDataSourceOrThrow().getCurrentStageKey()
+        return currentStageKey == UIADataSource.ENROLL_EMAIL_REQUEST_TOKEN_TYPE
+                || currentStageKey == UIADataSource.ENROLL_EMAIL_SUBMIT_TOKEN_TYPE
+    }
 
     private fun validationCodeSentState() {
         showSuccess(getString(R.string.validation_code_sent_to_format, getEmailInput()))
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
index b7a1b86fd..c0e1a3a3d 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/uia/stages/validate_email/ValidateEmailViewModel.kt
@@ -18,7 +18,7 @@ class ValidateEmailViewModel @Inject constructor(
     val validateEmailLiveData = SingleEventLiveData<Response<RegistrationResult>>()
 
     val showSubscribeCheckLiveData = MutableLiveData(dataSource.shouldShowSubscribeToEmail())
-    val usersEmailLiveData = MutableLiveData(dataSource.getPrefilledEmail())
+    val usersEmailLiveData = MutableLiveData(dataSource.getUsersEmails())
 
     fun sendCode(email: String, subscribeToUpdates: Boolean) {
         launchBg {
diff --git a/auth/src/main/res/layout/fragment_validate_email.xml b/auth/src/main/res/layout/fragment_validate_email.xml
index e93507803..5658acfe2 100644
--- a/auth/src/main/res/layout/fragment_validate_email.xml
+++ b/auth/src/main/res/layout/fragment_validate_email.xml
@@ -38,38 +38,53 @@
         android:layout_height="wrap_content"
         android:gravity="center"
         android:text="@string/validate_your_email"
-        app:layout_constraintBottom_toTopOf="@id/tilEmail"
+        app:layout_constraintBottom_toTopOf="@id/lEmailInput"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/guidelineLogo"
         app:layout_constraintVertical_bias="0.15"
         app:layout_constraintVertical_chainStyle="packed" />
 
-    <com.google.android.material.textfield.TextInputLayout
-        android:id="@+id/tilEmail"
-        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+    <FrameLayout
+        android:id="@+id/lEmailInput"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginTop="16dp"
-        android:hint="@string/email"
-        app:endIconDrawable="@drawable/ic_info"
-        app:endIconMode="custom"
-        app:endIconTint="@color/blue"
         app:layout_constraintBottom_toTopOf="@id/btnValidate"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/tvValidateTitle">
 
-        <com.google.android.material.textfield.TextInputEditText
-            android:id="@+id/etEmail"
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/tilEmail"
+            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:imeOptions="actionDone"
-            android:inputType="textEmailAddress"
-            android:maxLines="1"
-            android:padding="12dp" />
+            android:hint="@string/email"
+            app:endIconDrawable="@drawable/ic_info"
+            app:endIconMode="custom"
+            app:endIconTint="@color/blue">
 
-    </com.google.android.material.textfield.TextInputLayout>
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/etEmail"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:imeOptions="actionDone"
+                android:inputType="textEmailAddress"
+                android:maxLines="1"
+                android:padding="12dp" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <Spinner
+            android:id="@+id/spEmail"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingVertical="12dp"
+            android:visibility="gone"
+            tools:visibility="visible" />
+
+    </FrameLayout>
 
     <com.google.android.material.textfield.TextInputLayout
         android:id="@+id/tilValidationCode"
@@ -107,9 +122,9 @@
         android:enabled="false"
         android:text="@string/send_validation_code"
         android:textSize="12sp"
-        app:layout_constraintEnd_toEndOf="@id/tilEmail"
+        app:layout_constraintEnd_toEndOf="@id/lEmailInput"
         app:layout_constraintStart_toEndOf="@id/guidelineCenterVertical"
-        app:layout_constraintTop_toBottomOf="@id/tilEmail" />
+        app:layout_constraintTop_toBottomOf="@id/lEmailInput" />
 
     <com.google.android.material.checkbox.MaterialCheckBox
         android:id="@+id/cbEmailUpdates"
-- 
GitLab