diff --git a/app/build.gradle b/app/build.gradle index ad2458dde3..c8aee1e0f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,6 +33,11 @@ android { } } +repositories { + mavenCentral() + google() +} + dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" @@ -59,4 +64,6 @@ dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2' implementation 'com.itkacher.okhttpprofiler:okhttpprofiler:1.0.5' + implementation 'com.github.bumptech.glide:glide:4.10.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0' } diff --git a/app/src/main/java/com/navi/medici/androidCustomerApp/api/KycDocumentUploadApi.kt b/app/src/main/java/com/navi/medici/androidCustomerApp/api/KycDocumentUploadApi.kt index 26be1dc248..ad3c68c0d9 100644 --- a/app/src/main/java/com/navi/medici/androidCustomerApp/api/KycDocumentUploadApi.kt +++ b/app/src/main/java/com/navi/medici/androidCustomerApp/api/KycDocumentUploadApi.kt @@ -5,7 +5,10 @@ import com.navi.medici.androidCustomerApp.models.response.UploadDocumentResponse import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Response -import retrofit2.http.* +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Path interface KycDocumentUploadApi { @Multipart @@ -14,7 +17,7 @@ interface KycDocumentUploadApi { @Multipart @POST("/loan-origination-manager/loan-applications/{loanApplicationId}/selfie") - suspend fun submitSelfie(@Part("type") type: RequestBody, @Part file: MultipartBody.Part): Response + suspend fun submitSelfie(@Path("loanApplicationId") loanApplicationId: String, @Part("type") type: RequestBody, @Part file: MultipartBody.Part): Response companion object { operator fun invoke(): KycDocumentUploadApi { diff --git a/app/src/main/java/com/navi/medici/androidCustomerApp/repositories/KycDocumentUploadRepository.kt b/app/src/main/java/com/navi/medici/androidCustomerApp/repositories/KycDocumentUploadRepository.kt index 465b8dd021..eb55b593d6 100644 --- a/app/src/main/java/com/navi/medici/androidCustomerApp/repositories/KycDocumentUploadRepository.kt +++ b/app/src/main/java/com/navi/medici/androidCustomerApp/repositories/KycDocumentUploadRepository.kt @@ -15,9 +15,10 @@ class KycDocumentUploadRepository(private val kycDocumentUploadApi: KycDocumentU ) }.invoke() - suspend fun submitSelfie(@Part type: RequestBody, @Part file: MultipartBody.Part) = + suspend fun submitSelfie(loanApplicationId: String, @Part type: RequestBody, @Part file: MultipartBody.Part) = suspend { kycDocumentUploadApi.submitSelfie( + loanApplicationId, type, file ) diff --git a/app/src/main/java/com/navi/medici/androidCustomerApp/ui/fragments/KycDocumentUploadFragment.kt b/app/src/main/java/com/navi/medici/androidCustomerApp/ui/fragments/KycDocumentUploadFragment.kt index ed6d24e264..7bd03cfc80 100644 --- a/app/src/main/java/com/navi/medici/androidCustomerApp/ui/fragments/KycDocumentUploadFragment.kt +++ b/app/src/main/java/com/navi/medici/androidCustomerApp/ui/fragments/KycDocumentUploadFragment.kt @@ -19,19 +19,17 @@ import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders +import com.bumptech.glide.Glide import com.navi.medici.androidCustomerApp.R import com.navi.medici.androidCustomerApp.common.PreferenceManager import com.navi.medici.androidCustomerApp.databinding.KycDocumentUploadFragmentBinding import com.navi.medici.androidCustomerApp.ui.activities.BottomNavigationActivity import com.navi.medici.androidCustomerApp.viewModels.KycDocumentUploadViewModel import java.io.ByteArrayOutputStream -import java.io.File -import java.io.FileOutputStream class KycDocumentUploadFragment : Fragment() { private lateinit var binding: KycDocumentUploadFragmentBinding private lateinit var viewModel: KycDocumentUploadViewModel - private var bitmap: Bitmap? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -59,22 +57,47 @@ class KycDocumentUploadFragment : Fragment() { binding.continueButton.setOnClickListener { onClickContinueButton() } binding.selfieUploadButton.setOnClickListener { onClickSelfieUploadButton() } - viewModel.showMessage.observe(this, showToastObserver()) + viewModel.poaDocumentUploadUri.observe(this, poaDocumentUploadObserver()) + viewModel.selfieUploadUri.observe(this, selfieUploadObserver()) + return binding.root } - private fun onClickSelfieUploadButton() { - val intent: Intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) - intent.putExtra("android.intent.extras.CAMERA_FACING", 1); - startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) + private fun selfieUploadObserver(): Observer { + return Observer { + it?.let { image -> + binding.selfieProgress.visibility = View.GONE + binding.selfiePreview.visibility = View.VISIBLE + Glide.with(this).load(image).centerCrop().into(binding.selfiePreview) + } ?: run { + binding.selfieBeforeUploadPreview.visibility = View.VISIBLE + binding.selfieAfterUploadPreview.visibility = View.GONE + Toast.makeText(activity, getString(R.string.upload_failed), Toast.LENGTH_LONG) + .show() + } + } } - private fun showToastObserver(): Observer { + private fun poaDocumentUploadObserver(): Observer { return Observer { - Toast.makeText(activity, it, Toast.LENGTH_LONG).show() + it?.let { image -> + binding.poaProgress.visibility = View.GONE + binding.poaPreview.visibility = View.VISIBLE + Glide.with(this).load(image).centerCrop().into(binding.poaPreview) + } ?: run { + binding.poaBeforeUploadPreview.visibility = View.VISIBLE + binding.poaAfterUploadPreview.visibility = View.GONE + Toast.makeText(activity, getString(R.string.upload_failed), Toast.LENGTH_LONG) + .show() + } } } + private fun onClickSelfieUploadButton() { + val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) + } + private fun onClickContinueButton() { (activity as BottomNavigationActivity).onClickBottomNavigationMenuItem(MyLoansFragment.TAG) } @@ -100,21 +123,23 @@ class KycDocumentUploadFragment : Fragment() { super.onActivityResult(requestCode, resultCode, intent) if (requestCode == FILE_SELECT_CODE) { intent?.data?.let { uri -> + binding.poaBeforeUploadPreview.visibility = View.INVISIBLE + binding.poaAfterUploadPreview.visibility = View.VISIBLE + binding.poaType.text = viewModel.documentSelectedForUpload.value activity?.contentResolver?.openInputStream(uri)?.readBytes()?.let { - viewModel.submitPoaDocument(it, getLoanApplicationId().toString()) + viewModel.submitPoaDocument(it, getLoanApplicationId()) } } } if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { intent?.extras?.let { - bitmap = it?.get("data") as? Bitmap - binding.selfieUploadButton.visibility = View.GONE - binding.previewImage.visibility = View.VISIBLE - binding.previewImage.setImageBitmap(bitmap) + val bitmapImage = it.get("data") as Bitmap + binding.selfieBeforeUploadPreview.visibility = View.GONE + binding.selfieAfterUploadPreview.visibility = View.VISIBLE val outputStream = ByteArrayOutputStream() - bitmap?.compress(Bitmap.CompressFormat.JPEG, 0, outputStream) - viewModel.submitSelfie(outputStream.toByteArray()) + bitmapImage.compress(Bitmap.CompressFormat.JPEG, 0, outputStream) + viewModel.submitSelfie(outputStream.toByteArray(), getLoanApplicationId()) } } } @@ -141,7 +166,15 @@ class KycDocumentUploadFragment : Fragment() { position: Int, id: Long ) { - binding.uploadDocumentButton.isEnabled = position != 0 + if (position != 0) { + binding.uploadDocumentButton.visibility = View.VISIBLE + binding.uploadDocumentButton.text = getString( + R.string.upload_document_button_label, + parent?.selectedItem.toString() + ) + } else { + binding.uploadDocumentButton.visibility = View.INVISIBLE + } viewModel.documentSelectedForUpload.value = parent?.selectedItem.toString() } @@ -163,7 +196,6 @@ class KycDocumentUploadFragment : Fragment() { ) } - companion object { const val TAG = "KYC_DOCUMENT_UPLOAD_FRAGMENT" private const val FILE_SELECT_CODE = 100 diff --git a/app/src/main/java/com/navi/medici/androidCustomerApp/viewModels/KycDocumentUploadViewModel.kt b/app/src/main/java/com/navi/medici/androidCustomerApp/viewModels/KycDocumentUploadViewModel.kt index e1774917d8..5cc297b913 100644 --- a/app/src/main/java/com/navi/medici/androidCustomerApp/viewModels/KycDocumentUploadViewModel.kt +++ b/app/src/main/java/com/navi/medici/androidCustomerApp/viewModels/KycDocumentUploadViewModel.kt @@ -10,13 +10,15 @@ import kotlinx.coroutines.launch import okhttp3.MediaType import okhttp3.MultipartBody import okhttp3.RequestBody +import timber.log.Timber class KycDocumentUploadViewModel : ViewModel() { val proofOfAddresses = arrayOf("Choose POA Document", "Aadhar card", "PAN card") private val kycDocumentUploadRepository = KycDocumentUploadRepository(KycDocumentUploadApi()) private val coroutineScope = CoroutineScope(Dispatchers.Main) val documentSelectedForUpload = MutableLiveData() - val showMessage = MutableLiveData() + val poaDocumentUploadUri = MutableLiveData() + val selfieUploadUri = MutableLiveData() fun submitPoaDocument(bytes: ByteArray, loanApplicationId: String?) { val reqFile = RequestBody.create( @@ -31,16 +33,22 @@ class KycDocumentUploadViewModel : ViewModel() { ) coroutineScope.launch { loanApplicationId?.let { loanApplicationId -> - kycDocumentUploadRepository.submitPoaDocument( + val response = kycDocumentUploadRepository.submitPoaDocument( loanApplicationId, requestType, body ) + Timber.i("POA document upload ${response.body()}") + if (response.isSuccessful) { + poaDocumentUploadUri.value = response.body()?.uri + } else { + poaDocumentUploadUri.value = null + } } } } - fun submitSelfie(bytes: ByteArray) { + fun submitSelfie(bytes: ByteArray, loanApplicationId: String?) { val reqFile = RequestBody.create( MediaType.parse("application/x-www-form-urlencoded"), bytes @@ -52,10 +60,19 @@ class KycDocumentUploadViewModel : ViewModel() { ) coroutineScope.launch { - val response = kycDocumentUploadRepository.submitSelfie( - requestType, - body - ) + loanApplicationId?.let { loanApplicationId -> + val response = kycDocumentUploadRepository.submitSelfie( + loanApplicationId, + requestType, + body + ) + Timber.i("Selfie upload ${response.body()}") + if (response.isSuccessful) { + selfieUploadUri.value = response.body()?.uri + } else { + selfieUploadUri.value = null + } + } } } } diff --git a/app/src/main/res/drawable/poa_icon.png b/app/src/main/res/drawable/poa_icon.png new file mode 100644 index 0000000000..0601058706 Binary files /dev/null and b/app/src/main/res/drawable/poa_icon.png differ diff --git a/app/src/main/res/drawable/poa_icon_fix.xml b/app/src/main/res/drawable/poa_icon_fix.xml new file mode 100644 index 0000000000..ce01f3dab6 --- /dev/null +++ b/app/src/main/res/drawable/poa_icon_fix.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/upload_button_background_selector.xml b/app/src/main/res/drawable/upload_button_background_selector.xml deleted file mode 100644 index f7cabdf188..0000000000 --- a/app/src/main/res/drawable/upload_button_background_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/upload_button_color_selector.xml b/app/src/main/res/drawable/upload_button_color_selector.xml deleted file mode 100644 index 58a7a4fef3..0000000000 --- a/app/src/main/res/drawable/upload_button_color_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/kyc_document_upload_fragment.xml b/app/src/main/res/layout/kyc_document_upload_fragment.xml index 3266c114a4..57c5abe90c 100644 --- a/app/src/main/res/layout/kyc_document_upload_fragment.xml +++ b/app/src/main/res/layout/kyc_document_upload_fragment.xml @@ -1,121 +1,228 @@ - + - - - + android:layout_marginBottom="16dp" + android:gravity="center_vertical"> - + - - + android:layout_height="wrap_content" + android:text="@string/proof_of_address_label_text" /> + -