diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..bc0e6a19d5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,34 @@ + + + + +## Description of what I changed + + + + +## Issue I worked on + + +JIRA Issue: https://navihq.atlassian.net/browse/AE-#### + +## Type of change I made + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected, explain why) +- [ ] Refactoring / Maintenance (non-breaking change to keep the project healthy) + +## QA Requirement for my changes + +- [ ] QA is required for this change (QA Owner: @github-username) +- [ ] QA is not required for this change + +## Checklist: I completed these to help reviewers :) + +- [ ] I am able to build the project locally with my changes +- [ ] My changes generate no new warnings +- [ ] My code follows the style guidelines of this project & spotless check passes +- [ ] I have performed a self-review of my own code +- [ ] I have made corresponding changes to the documentation +- [ ] I understand that **'Squash and merge'** is the preferred merge diff --git a/.gitignore b/.gitignore index c2ee5999ab..323a669793 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ *.class *.log vcs.xml -digio-kyc-3.1.5/build +digio-kyc-3.1.7/build digio-esign-v2.8.9/build one-money-sdk/build truecallersdk-2.6.1-releasePartner/build @@ -24,4 +24,5 @@ finoramic-android-sdk/build finoramic-androidx-sdk/build/ local.env # Local build cache -build-cache \ No newline at end of file +build-cache +api-credentials.json diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000..7a118b49be --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000..885cc70fce --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,218 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.5) + rexml + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + artifactory (3.0.15) + atomos (0.1.3) + aws-eventstream (1.2.0) + aws-partitions (1.650.0) + aws-sdk-core (3.164.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.525.0) + aws-sigv4 (~> 1.1) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.58.0) + aws-sdk-core (~> 3, >= 3.127.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.116.0) + aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.4) + aws-sigv4 (1.5.2) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) + claide (1.1.0) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + declarative (0.0.20) + digest-crc (0.6.4) + rake (>= 12.0.0, < 14.0.0) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.8.1) + emoji_regex (3.2.3) + excon (0.93.1) + faraday (1.10.2) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-cookie_jar (0.0.7) + faraday (>= 0.8.0) + http-cookie (~> 1.0.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) + fastimage (2.2.6) + fastlane (2.210.1) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.0) + babosa (>= 1.0.3, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander (~> 4.6) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 4.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 1.0) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 1.0) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.3) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) + json (< 3.0.0) + jwt (>= 2.1.0, < 3) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (~> 2.0.0) + naturally (~> 2.2) + optparse (~> 0.1.1) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 2.0.0, < 3.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + gh_inspector (1.1.3) + google-apis-androidpublisher_v3 (0.29.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-core (0.9.1) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.16.2, < 2.a) + httpclient (>= 2.8.1, < 3.a) + mini_mime (~> 1.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.a) + rexml + webrick + google-apis-iamcredentials_v1 (0.15.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-playcustomapp_v1 (0.12.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) + google-cloud-core (1.6.0) + google-cloud-env (~> 1.0) + google-cloud-errors (~> 1.0) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.0) + google-cloud-storage (1.43.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-iamcredentials_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) + google-cloud-core (~> 1.6) + googleauth (>= 0.16.2, < 2.a) + mini_mime (~> 1.0) + googleauth (1.3.0) + faraday (>= 0.17.3, < 3.a) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + highline (2.0.3) + http-cookie (1.0.5) + domain_name (~> 0.5) + httpclient (2.8.3) + jmespath (1.6.1) + json (2.6.2) + jwt (2.5.0) + memoist (0.16.2) + mini_magick (4.11.0) + mini_mime (1.1.2) + multi_json (1.15.0) + multipart-post (2.0.0) + nanaimo (0.3.0) + naturally (2.2.1) + optparse (0.1.1) + os (1.1.4) + plist (3.6.0) + public_suffix (5.0.0) + rake (13.0.6) + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rexml (3.2.5) + rouge (2.0.7) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + security (0.1.3) + signet (0.17.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.8) + CFPropertyList + naturally + terminal-notifier (2.0.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + trailblazer-option (0.1.2) + tty-cursor (0.7.1) + tty-screen (0.8.1) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + webrick (1.7.0) + word_wrap (1.0.0) + xcodeproj (1.22.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + x86_64-darwin-21 + +DEPENDENCIES + fastlane + +BUNDLED WITH + 2.3.11 diff --git a/app/build.gradle b/app/build.gradle index 025cc1490f..588ec51dbf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,7 @@ kapt { correctErrorTypes true } -def VERSION_NAME = "3.0.4" +def VERSION_NAME = "3.0.5" android { compileSdkVersion 32 @@ -46,7 +46,7 @@ android { applicationId "com.naviapp" minSdkVersion 21 targetSdk 31 - versionCode 275 + versionCode 276 versionName VERSION_NAME multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -261,6 +261,7 @@ publishing { } dependencies { + implementation project(":navi-vkyc") implementation project(":navi-common") implementation project(":navi-chat") androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' diff --git a/app/src/androidTestDev/java/com/naviapp/a2d/tests/mock_tests/NsdlMockTests.kt b/app/src/androidTestDev/java/com/naviapp/a2d/tests/mock_tests/NsdlMockTests.kt index f21b9b6f2f..6541d8d4bc 100644 --- a/app/src/androidTestDev/java/com/naviapp/a2d/tests/mock_tests/NsdlMockTests.kt +++ b/app/src/androidTestDev/java/com/naviapp/a2d/tests/mock_tests/NsdlMockTests.kt @@ -117,7 +117,7 @@ class NsdlMockTests:TestBase() { .clickNext() .enterWorkDetails(workDetails) .clickNext() - .enterPan("AENPK0575P") + .enterPan("AAAAA1234A") .enterOtherDetails() .submitApplication() .submitApplication() diff --git a/app/src/androidTestLibrary/java/com/naviapp/constants/StringType.kt b/app/src/androidTestLibrary/java/com/naviapp/constants/StringType.kt index 85c18acab4..db8f35d86c 100644 --- a/app/src/androidTestLibrary/java/com/naviapp/constants/StringType.kt +++ b/app/src/androidTestLibrary/java/com/naviapp/constants/StringType.kt @@ -34,7 +34,7 @@ object StringType { } object Pan { - const val panNumber = "AUXHG1234G" + const val panNumber = "AAAAA1234A" } object Kyc { diff --git a/app/src/androidTestMockServer/java/com/naviappmockserver/contract/ServerResponse.kt b/app/src/androidTestMockServer/java/com/naviappmockserver/contract/ServerResponse.kt index 1ef1b45a01..be17eab338 100644 --- a/app/src/androidTestMockServer/java/com/naviappmockserver/contract/ServerResponse.kt +++ b/app/src/androidTestMockServer/java/com/naviappmockserver/contract/ServerResponse.kt @@ -321,7 +321,7 @@ data class UserDetail( val employmentType: String? = "Student", val companyName: String? = "Infosys", val monthlyIncome: Money? = Money(BigDecimal.valueOf(30000)), - val panNumber: String? = "ABCDE1234F" + val panNumber: String? = "ABCTY1234E" ) enum class RequestType { diff --git a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/activityTests/useridentification/pan/PanFragmentSoftRejectTest.kt b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/activityTests/useridentification/pan/PanFragmentSoftRejectTest.kt index 5278d6838a..b996e690c7 100644 --- a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/activityTests/useridentification/pan/PanFragmentSoftRejectTest.kt +++ b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/activityTests/useridentification/pan/PanFragmentSoftRejectTest.kt @@ -58,7 +58,7 @@ class PanFragmentSoftRejectTest : LoanEligibilityMockTestBase() { /*@Test fun shouldHandleSoftRejectOnPanFragment() { - onView(ViewMatchers.withId(R.id.pan_card_number_et)).perform(ViewActions.typeText("AXWZN1234M")) + onView(ViewMatchers.withId(R.id.pan_card_number_et)).perform(ViewActions.typeText("AAECC7456R")) .perform(ViewActions.closeSoftKeyboard()) dispatcher.softReject( diff --git a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/LoanEligibilityUserJourney.kt b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/LoanEligibilityUserJourney.kt index dfe5627e1d..2c499a33d7 100644 --- a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/LoanEligibilityUserJourney.kt +++ b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/LoanEligibilityUserJourney.kt @@ -139,7 +139,7 @@ class LoanEligibilityUserJourney : AbstractCustomerAppTestCase() { withId(R.id.pan_card_number_et), 1000 ) - onView(withId(R.id.pan_card_number_et)).perform(typeText("AXWZN1234M")) + onView(withId(R.id.pan_card_number_et)).perform(typeText("AAECC7456R")) .perform(closeSoftKeyboard()) onView(allOf(withId(R.id.check_eligibility_button), isDisplayed())).perform(click()) loanEligibilityDispatcher.await( diff --git a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/PanDetails.kt b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/PanDetails.kt index 3001691885..2645e8b55a 100644 --- a/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/PanDetails.kt +++ b/app/src/androidTestMockServer/java/com/naviappmockserver/instrumentedTests/loaneligibility/PanDetails.kt @@ -154,7 +154,7 @@ class PanDetails : AbstractCustomerAppTestCase() { Controller .on() .verifyOnThisActivity() - .enterPan("ABCDE1234F") + .enterPan("AAECC7456R") .submitApplication(waitForLoader = false) } diff --git a/app/src/main/java/com/naviapp/analytics/utils/NaviAnalytics.kt b/app/src/main/java/com/naviapp/analytics/utils/NaviAnalytics.kt index 044b7f1e50..d4d4f71748 100644 --- a/app/src/main/java/com/naviapp/analytics/utils/NaviAnalytics.kt +++ b/app/src/main/java/com/naviapp/analytics/utils/NaviAnalytics.kt @@ -34,9 +34,9 @@ import com.naviapp.models.response.RadioButtonResponse import com.naviapp.models.response.WidgetConfig import com.naviapp.personalloanrevamp.models.KycItemV2 import com.naviapp.utils.* +import okhttp3.internal.toImmutableMap import java.util.* import java.util.concurrent.ConcurrentHashMap -import okhttp3.internal.toImmutableMap @Keep class NaviAnalytics private constructor() { @@ -288,10 +288,20 @@ class NaviAnalytics private constructor() { fun onStartVkycClicked() { NaviTrackEvent.trackEvent("PL_KYC_StartVKYC_Clicked") + NaviTrackEvent.trackEvent("PL_StartVKYC_Clicked") + } + + fun onShowVkycCard() { + NaviTrackEvent.trackEvent("PL_StartVKYC_Shown") } fun onPanVkycClicked() { NaviTrackEvent.trackEvent("PL_KYC_VKYC_PAN_Clicked") + NaviTrackEvent.trackEvent("PL_VKYC_PAN_Upload_Clicked") + } + + fun onLandedOnPanPage() { + NaviTrackEvent.trackEvent("PL_PAN_Upload_Page_Lands") } fun onVkycItemClicked(type: String?) { @@ -1348,7 +1358,7 @@ class NaviAnalytics private constructor() { } } - inner class EffectiveInterestCost() { + inner class EffectiveInterestCost { fun onEffectiveInterestCostPageLand() { NaviTrackEvent.trackEvent("PL_EIC_Detail_Page_Landing") } @@ -5129,6 +5139,38 @@ class NaviAnalytics private constructor() { } } + inner class HomeLoanLandingPageEvent { + + fun onScreenLandingEvent(screenName: String, isLoggedIn: Boolean) { + NaviTrackEvent.trackEventOnClickStream( + NEW_HL_LANDING_LOADED, + mapOf( + Pair("screen_name", screenName), + Pair("timestamp", System.currentTimeMillis().toString()), + Pair("login_status", if (isLoggedIn) "yes" else "no") + ) + ) + } + + fun onBenefitsCardClicked(cta: CtaData?) { + cta?.analyticsEventProperties?.name?.let { name -> + NaviTrackEvent.trackEventOnClickStream( + name, + cta.analyticsEventProperties?.properties ?: mutableMapOf() + ) + } + } + + fun onVideoCardClicked(cta: CtaData?) { + cta?.analyticsEventProperties?.name?.let { name -> + NaviTrackEvent.trackEventOnClickStream( + name, + cta.analyticsEventProperties?.properties ?: mutableMapOf() + ) + } + } + } + inner class OfferRejection { fun onOfferRejectionPageLands(rejectionDate: String?) { NaviTrackEvent.trackEvent( @@ -5722,6 +5764,7 @@ class NaviAnalytics private constructor() { const val PL_VIEWDETAILS_LANDS = "PL_ViewDetails_Lands" const val HL_VIEWDETAILS_LANDS = "HL_ViewDetails_Lands" + const val HL_LANDING_PAGE = "HL_Landing_Page" const val PROPERTY_OPTION = "option" const val LOGIN_FLAG = "login_flag" @@ -5742,5 +5785,7 @@ class NaviAnalytics private constructor() { const val REWARDS_ANNOUNCEMENT_SCREEN = "rewards_announcement_screen" const val POST_PAYMENT_MESSAGING_SCREEN = "Post_Payment_Messaging_Screen" + + const val NEW_HL_LANDING_LOADED = "New_HL_Landing_Loaded" } } diff --git a/app/src/main/java/com/naviapp/common/customview/CreditScoreView.kt b/app/src/main/java/com/naviapp/common/customview/CreditScoreView.kt index 2c527128a6..4ab9d9ce47 100644 --- a/app/src/main/java/com/naviapp/common/customview/CreditScoreView.kt +++ b/app/src/main/java/com/naviapp/common/customview/CreditScoreView.kt @@ -106,10 +106,11 @@ class CreditScoreView @JvmOverloads constructor( progressBar: CircularProgressIndicator, constraintSet: ConstraintSet ) { - progressBar.layoutParams = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT - ) + progressBar.layoutParams = + FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) constraintSet.clone(binding.progressView) constraintSet.connect( progressBar.id, @@ -140,4 +141,4 @@ class CreditScoreView @JvmOverloads constructor( 0 ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/customview/EmiPlansView.kt b/app/src/main/java/com/naviapp/common/customview/EmiPlansView.kt index d181dfcb9f..6a896831a0 100644 --- a/app/src/main/java/com/naviapp/common/customview/EmiPlansView.kt +++ b/app/src/main/java/com/naviapp/common/customview/EmiPlansView.kt @@ -40,10 +40,8 @@ class EmiPlansView(context: Context, attrs: AttributeSet? = null) : } binding.iconIv.visibility = View.GONE emiPlansCardData.iconCode?.let { - LoanDetailsFragment().onEffectiveInterestCostIconView( - "emi_plans_card", - emiPlansCardData.subTitle - ) + LoanDetailsFragment() + .onEffectiveInterestCostIconView("emi_plans_card", emiPlansCardData.subTitle) binding.iconIv.visibility = View.VISIBLE binding.iconIv.setImageResource(NaviWidgetIconUtils.getIconResourceId(it)) emiPlansCardData.iconCta?.let { ctaData -> @@ -54,4 +52,4 @@ class EmiPlansView(context: Context, attrs: AttributeSet? = null) : } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/customview/RadioOptionView.kt b/app/src/main/java/com/naviapp/common/customview/RadioOptionView.kt index 42b5ef724b..cfd37bbc66 100644 --- a/app/src/main/java/com/naviapp/common/customview/RadioOptionView.kt +++ b/app/src/main/java/com/naviapp/common/customview/RadioOptionView.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,12 +13,12 @@ import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout import androidx.core.content.ContextCompat +import com.navi.common.utils.setCornerRadius import com.naviapp.R import com.naviapp.databinding.RadioOptionViewBinding -import com.naviapp.utils.setCornerRadius -class RadioOptionView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs), - View.OnClickListener { +class RadioOptionView(context: Context, attrs: AttributeSet) : + LinearLayout(context, attrs), View.OnClickListener { private val binding: RadioOptionViewBinding private lateinit var tag: OptionTag private var listener: RadioOptionViewListener? = null @@ -60,21 +60,25 @@ class RadioOptionView(context: Context, attrs: AttributeSet) : LinearLayout(cont fun setInfoIcon(action: (() -> Unit)? = null) { binding.infoButton.visibility = View.VISIBLE - binding.infoButton.setOnClickListener { - action?.invoke() - } + binding.infoButton.setOnClickListener { action?.invoke() } } fun onClickKycOption(isSelected: Boolean) { if (isSelected) { binding.checkedIv.visibility = View.VISIBLE binding.titleTv.setTextColor(ContextCompat.getColor(context, R.color.title_color_one)) - binding.parentView.setBackgroundResource(R.drawable.bg_rounded_deepbluegray_6_with_deepbluegray_border) + binding.parentView.setBackgroundResource( + R.drawable.bg_rounded_deepbluegray_6_with_deepbluegray_border + ) listener?.onSelectOptionTag(tag) } else { binding.checkedIv.visibility = View.INVISIBLE - binding.titleTv.setTextColor(ContextCompat.getColor(context, R.color.view_background_color_five)) - binding.parentView.setBackgroundResource(R.drawable.bg_rounded_transparent_6_with_lightgray_border) + binding.titleTv.setTextColor( + ContextCompat.getColor(context, R.color.view_background_color_five) + ) + binding.parentView.setBackgroundResource( + R.drawable.bg_rounded_transparent_6_with_lightgray_border + ) } } @@ -95,6 +99,8 @@ class RadioOptionView(context: Context, attrs: AttributeSet) : LinearLayout(cont } enum class OptionTag { - NET_BANKING, UPLOAD_BANK_STATEMENT, ACCOUNT_AGGREGATOR + NET_BANKING, + UPLOAD_BANK_STATEMENT, + ACCOUNT_AGGREGATOR } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/customview/RadioSelectorItemView.kt b/app/src/main/java/com/naviapp/common/customview/RadioSelectorItemView.kt index ff326f0383..df9af449f0 100644 --- a/app/src/main/java/com/naviapp/common/customview/RadioSelectorItemView.kt +++ b/app/src/main/java/com/naviapp/common/customview/RadioSelectorItemView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.customview /* * @@ -20,10 +27,10 @@ import com.naviapp.utils.formatCurrency import com.naviapp.utils.formatTenure import com.naviapp.utils.getEmiValue -class RadioSelectorItemView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : LinearLayout(context, attrs), SliderWithTooltipView.TooltipChangeListener { +class RadioSelectorItemView +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null) : + LinearLayout(context, attrs), SliderWithTooltipView.TooltipChangeListener { var viewSelected = true var selectedTenure: Int? = 0 @@ -33,9 +40,8 @@ class RadioSelectorItemView @JvmOverloads constructor( private var additionalData: LoanDetailsV2AdditionData? = null private var listener: TenureChangeListener? = null - private val binding = RadioSelectorItemViewBinding.inflate( - LayoutInflater.from(context), this, true - ) + private val binding = + RadioSelectorItemViewBinding.inflate(LayoutInflater.from(context), this, true) init { isClickable = true @@ -126,7 +132,7 @@ class RadioSelectorItemView @JvmOverloads constructor( return this } - fun setSelectedValue(selectedValue : Int , minValue: Int , maxValue: Int){ + fun setSelectedValue(selectedValue: Int, minValue: Int, maxValue: Int) { binding.sliderTooltipView.setSelectedTenureValue(selectedValue - minValue) } @@ -154,20 +160,32 @@ class RadioSelectorItemView @JvmOverloads constructor( } } - override fun onProgressEnd(progress: Int, tenureInMonth: Double,currentProgressPercentage : Double) { + override fun onProgressEnd( + progress: Int, + tenureInMonth: Double, + currentProgressPercentage: Double + ) { additionalData?.loanAmount?.amount?.let { amount -> additionalData?.rateOfInterest?.let { rateOfInterest -> selectedTenure = tenureInMonth.toInt() val emi = getEmiValue(amount, rateOfInterest, tenureInMonth.toInt()) emiAsPerTenure = emi?.toDouble() binding.amountTv.text = emi?.toDouble()?.formatCurrency() - listener?.onTenureSliderEnd(selectedTenure, emiAsPerTenure,currentProgressPercentage) + listener?.onTenureSliderEnd( + selectedTenure, + emiAsPerTenure, + currentProgressPercentage + ) } } } interface TenureChangeListener { fun onTenureChanged(tenureValue: Int?, monthlyEmi: Double?) - fun onTenureSliderEnd(tenureValue: Int?, monthlyEmi: Double?, currentProgressPercentage: Double) + fun onTenureSliderEnd( + tenureValue: Int?, + monthlyEmi: Double?, + currentProgressPercentage: Double + ) } } diff --git a/app/src/main/java/com/naviapp/common/customview/SecurityTextWithIconView.kt b/app/src/main/java/com/naviapp/common/customview/SecurityTextWithIconView.kt index 5f87b15a0a..c23b1cf815 100644 --- a/app/src/main/java/com/naviapp/common/customview/SecurityTextWithIconView.kt +++ b/app/src/main/java/com/naviapp/common/customview/SecurityTextWithIconView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.customview import android.content.Context @@ -12,22 +19,18 @@ import com.naviapp.personalloanrevamp.models.response.SecurityTextWithIconWidget import com.naviapp.utils.makeUnderlined import com.naviapp.utils.setMargin +class SecurityTextWithIconView +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null) : ConstraintLayout(context, attrs) { -class SecurityTextWithIconView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : ConstraintLayout(context, attrs) { - - private val binding = SecurityTextWithIconLayoutBinding.inflate( - LayoutInflater.from(context), this, true - ) + private val binding = + SecurityTextWithIconLayoutBinding.inflate(LayoutInflater.from(context), this, true) init { layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) binding.knowMoreTv.makeUnderlined() } - fun setProperties( widgetConfig: SecurityTextWithIconWidgetConfig?, listener: LoanDetailsV2WidgetAdapterListener? @@ -38,5 +41,4 @@ class SecurityTextWithIconView @JvmOverloads constructor( listener?.onCtaClick(CtaData(type = LoanDetailsEditorFragment.CtaType.KNOW_MORE.value)) } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/customview/SelectorViewGroup.kt b/app/src/main/java/com/naviapp/common/customview/SelectorViewGroup.kt index 7774f4c9ea..bb8f37adf9 100644 --- a/app/src/main/java/com/naviapp/common/customview/SelectorViewGroup.kt +++ b/app/src/main/java/com/naviapp/common/customview/SelectorViewGroup.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.customview /* * @@ -15,7 +22,10 @@ import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import com.navi.base.model.CtaData import com.navi.base.model.LineItem +import com.navi.common.extensions.orFalse +import com.navi.common.utils.orZero import com.navi.design.utils.getNaviDrawable +import com.navi.design.utils.ifMeasured import com.naviapp.R import com.naviapp.models.response.LoanDetailsV2AdditionData import com.naviapp.personalloanrevamp.getloanRevamp.fragments.LoanDetailsEditorFragment @@ -24,18 +34,12 @@ import com.naviapp.personalloanrevamp.models.LoanDetailsV2WidgetType import com.naviapp.personalloanrevamp.models.RadioButtonParentConfigBody import com.naviapp.personalloanrevamp.models.RadioButtonWidgetListConfig import com.naviapp.utils.EMPTY -import com.navi.common.extensions.orFalse -import com.navi.common.utils.orZero -import com.navi.design.utils.ifMeasured import com.naviapp.utils.getEmiValue import com.naviapp.utils.orZero import com.naviapp.utils.setMargin - -class SelectorViewGroup @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : LinearLayout(context, attrs), RadioSelectorItemView.TenureChangeListener { +class SelectorViewGroup @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + LinearLayout(context, attrs), RadioSelectorItemView.TenureChangeListener { private var selectedRadioIndex = 0 private var additionalData: LoanDetailsV2AdditionData? = null @@ -49,12 +53,13 @@ class SelectorViewGroup @JvmOverloads constructor( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { outlineSpotShadowColor = ContextCompat.getColor(context, R.color.shadow_color) } - background = getNaviDrawable( - backgroundColor = ResourcesCompat.getColor(resources, R.color.white, null), - cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), - strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), - strokeColor = ResourcesCompat.getColor(resources, R.color.divider_gray, null) - ) + background = + getNaviDrawable( + backgroundColor = ResourcesCompat.getColor(resources, R.color.white, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), + strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), + strokeColor = ResourcesCompat.getColor(resources, R.color.divider_gray, null) + ) } fun setProperties( @@ -71,14 +76,16 @@ class SelectorViewGroup @JvmOverloads constructor( val itemView = getItemView(widgetData, index, listener) addView(itemView, childCount) - if (itemView.getShouldShowSlider() && - additionalData?.minTenureInMonths != null && - additionalData.maxTenureInMonths != null + if ( + itemView.getShouldShowSlider() && + additionalData?.minTenureInMonths != null && + additionalData.maxTenureInMonths != null ) { - itemView.setRanges( - additionalData.minTenureInMonths.toDouble(), - additionalData.maxTenureInMonths.toDouble() - ) + itemView + .setRanges( + additionalData.minTenureInMonths.toDouble(), + additionalData.maxTenureInMonths.toDouble() + ) .setMinMaxTitleValues( additionalData.minTenureInMonths.toDouble(), additionalData.maxTenureInMonths.toDouble(), @@ -107,30 +114,65 @@ class SelectorViewGroup @JvmOverloads constructor( index: Int, listener: LoanDetailsV2WidgetAdapterListener? ): RadioSelectorItemView { - val itemView = RadioSelectorItemView(context).apply { + val itemView = + RadioSelectorItemView(context).apply { + setTenureChangeListener(this@SelectorViewGroup) + setShouldShowSlider( + (widgetData.type == + LoanDetailsV2WidgetType.SELECTOR_WITH_SLIDER_RADIO_BUTTON.value) + ) + setData(widgetData, additionalData) - setTenureChangeListener(this@SelectorViewGroup) - setShouldShowSlider((widgetData.type == LoanDetailsV2WidgetType.SELECTOR_WITH_SLIDER_RADIO_BUTTON.value)) - setData(widgetData, additionalData) + if (widgetData.body?.defaultSelected?.orFalse() == true) { + selectedRadioIndex = index + setChecked() + onTenureSelected( + listener, + selectedTenure, + emiAsPerTenure, + getShouldShowSlider() + ) + val tenureAndEmi = + getTenureAndEmiForTenure( + selectedTenure, + emiAsPerTenure, + getShouldShowSlider() + ) + onTenureClicked( + listener, + tenureAndEmi.first, + tenureAndEmi.second, + getShouldShowSlider(), + LoanDetailsEditorFragment.CtaType.TENURE_DEFAULT_SELECTED.value + ) + } else { + setUnchecked() + } - if (widgetData.body?.defaultSelected?.orFalse() == true) { - selectedRadioIndex = index - setChecked() - onTenureSelected(listener, selectedTenure, emiAsPerTenure, getShouldShowSlider()) - val tenureAndEmi = getTenureAndEmiForTenure(selectedTenure,emiAsPerTenure,getShouldShowSlider()) - onTenureClicked(listener, tenureAndEmi.first, tenureAndEmi.second,getShouldShowSlider(),LoanDetailsEditorFragment.CtaType.TENURE_DEFAULT_SELECTED.value) - } else { - setUnchecked() + setOnClickListener { + selectedRadioIndex = index + markChecked(index) + onTenureSelected( + listener, + selectedTenure, + emiAsPerTenure, + getShouldShowSlider() + ) + val tenureAndEmi = + getTenureAndEmiForTenure( + selectedTenure, + emiAsPerTenure, + getShouldShowSlider() + ) + onTenureClicked( + listener, + tenureAndEmi.first, + tenureAndEmi.second, + getShouldShowSlider(), + LoanDetailsEditorFragment.CtaType.TENURE_CLICKED_TYPE.value + ) + } } - - setOnClickListener { - selectedRadioIndex = index - markChecked(index) - onTenureSelected(listener, selectedTenure, emiAsPerTenure,getShouldShowSlider()) - val tenureAndEmi = getTenureAndEmiForTenure(selectedTenure,emiAsPerTenure,getShouldShowSlider()) - onTenureClicked(listener, tenureAndEmi.first, tenureAndEmi.second,getShouldShowSlider(),LoanDetailsEditorFragment.CtaType.TENURE_CLICKED_TYPE.value) - } - } return itemView } @@ -159,7 +201,11 @@ class SelectorViewGroup @JvmOverloads constructor( onSliderChange(listener, tenureValue, monthlyEmi) } - override fun onTenureSliderEnd(tenureValue: Int?, monthlyEmi: Double?, currentProgressPercentage: Double) { + override fun onTenureSliderEnd( + tenureValue: Int?, + monthlyEmi: Double?, + currentProgressPercentage: Double + ) { onSliderEnd(listener, tenureValue, monthlyEmi, currentProgressPercentage) } @@ -182,20 +228,21 @@ class SelectorViewGroup @JvmOverloads constructor( listener?.onCtaClick( CtaData( type = LoanDetailsEditorFragment.CtaType.SLIDER_SELECTED_TYPE.value, - parameters = listOf( - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, - tenureValue.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, - monthlyEmi.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SLIDER_CHANGE.value, - EMPTY + parameters = + listOf( + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, + tenureValue.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, + monthlyEmi.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SLIDER_CHANGE.value, + EMPTY + ) ) - ) ) ) } @@ -210,20 +257,21 @@ class SelectorViewGroup @JvmOverloads constructor( listener?.onCtaClick( CtaData( type = LoanDetailsEditorFragment.CtaType.SLIDER_END_TYPE.value, - parameters = listOf( - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, - tenureValue.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, - monthlyEmi.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SLIDER_CHANGE.value, - EMPTY + parameters = + listOf( + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, + tenureValue.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, + monthlyEmi.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SLIDER_CHANGE.value, + EMPTY + ) ) - ) ) ) } @@ -237,20 +285,21 @@ class SelectorViewGroup @JvmOverloads constructor( listener?.onCtaClick( CtaData( type = LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_TYPE.value, - parameters = listOf( - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, - tenureValue.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, - monthlyEmi.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.CUSTOMISE_TENURE.value, - isCustomizeYourTenure.toString() + parameters = + listOf( + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, + tenureValue.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, + monthlyEmi.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.CUSTOMISE_TENURE.value, + isCustomizeYourTenure.toString() + ) ) - ) ), ) } @@ -265,22 +314,22 @@ class SelectorViewGroup @JvmOverloads constructor( listener?.onCtaClick( CtaData( type = type, - parameters = listOf( - LineItem( - LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, - tenureValue.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, - monthlyEmi.orZero().toString() - ), - LineItem( - LoanDetailsEditorFragment.CtaType.CUSTOMISE_TENURE.value, - isCustomizeYourTenure.toString() + parameters = + listOf( + LineItem( + LoanDetailsEditorFragment.CtaType.TENURE_SELECTED_VALUE.value, + tenureValue.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.MONTHLY_EMI_VALUE.value, + monthlyEmi.orZero().toString() + ), + LineItem( + LoanDetailsEditorFragment.CtaType.CUSTOMISE_TENURE.value, + isCustomizeYourTenure.toString() + ) ) - ) ), ) } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/customview/StrikedView.kt b/app/src/main/java/com/naviapp/common/customview/StrikedView.kt index 95d2e7c6cf..96182fcf36 100644 --- a/app/src/main/java/com/naviapp/common/customview/StrikedView.kt +++ b/app/src/main/java/com/naviapp/common/customview/StrikedView.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -16,17 +16,16 @@ import android.view.View import android.widget.LinearLayout import androidx.core.content.ContextCompat import androidx.databinding.DataBindingUtil -import com.navi.common.extensions.isNull import com.navi.base.model.StyledTextWithBgColorAndIconCode +import com.navi.common.extensions.isNull +import com.navi.common.extensions.orFalse +import com.navi.common.utils.makePartOfTextBold import com.naviapp.R import com.naviapp.databinding.ViewStrikeBinding import com.naviapp.models.TextStyle -import com.naviapp.utils.makePartOfTextBold -import com.navi.common.extensions.orFalse import com.naviapp.utils.setTextColorFromString -class StrikedView(context: Context?, attrs: AttributeSet? = null) : - LinearLayout(context, attrs) { +class StrikedView(context: Context?, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { private val binding: ViewStrikeBinding @@ -48,23 +47,19 @@ class StrikedView(context: Context?, attrs: AttributeSet? = null) : // if regular text is not null, then strike strikedText and apply style to regularText if (styledTextWithBgColorAndIconCode.isNull().not()) { binding.strikedTv.visibility = View.GONE - styledTextWithBgColorAndIconCode?.let { - styledText-> + styledTextWithBgColorAndIconCode?.let { styledText -> binding.regularTv.text = styledText.text styledText.bold?.let { boldText -> styledText.text?.let { text -> - binding.regularTv.makePartOfTextBold( - text, boldText - ) + binding.regularTv.makePartOfTextBold(text, boldText) } } binding.regularTv.setTextColorFromString(styledText.hexColorCode) - if(styledText.strikeText.orFalse()){ + if (styledText.strikeText.orFalse()) { binding.regularTv.paintFlags = binding.regularTv.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG } - binding.regularTv.textSize = resources.getInteger(R.integer.font_medium) - .toFloat() + binding.regularTv.textSize = resources.getInteger(R.integer.font_medium).toFloat() } } else if (regularText.isNullOrEmpty().not()) { binding.strikedTv.visibility = View.VISIBLE @@ -72,19 +67,14 @@ class StrikedView(context: Context?, attrs: AttributeSet? = null) : binding.strikedTv.paintFlags = binding.strikedTv.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG binding.strikedTv.setTextColor( - strikedTextStyle?.textColor ?: ContextCompat.getColor( - context, - R.color.description_color_one_opacity_70 - ) + strikedTextStyle?.textColor + ?: ContextCompat.getColor(context, R.color.description_color_one_opacity_70) ) binding.strikedTv.textSize = strikedTextStyle?.textSize ?: resources.getInteger(R.integer.font_small).toFloat() binding.regularTv.text = regularText binding.regularTv.setTextColor( - unStrikedTextStyle?.textColor ?: ContextCompat.getColor( - context, - R.color.green - ) + unStrikedTextStyle?.textColor ?: ContextCompat.getColor(context, R.color.green) ) binding.regularTv.textSize = unStrikedTextStyle?.textSize ?: resources.getInteger(R.integer.font_small).toFloat() @@ -93,20 +83,15 @@ class StrikedView(context: Context?, attrs: AttributeSet? = null) : binding.strikedTv.visibility = View.GONE binding.regularTv.text = strikedText binding.regularTv.setTextColor( - regularTextStyle?.textColor ?: ContextCompat.getColor( - context, - R.color.title_color_one - ) + regularTextStyle?.textColor + ?: ContextCompat.getColor(context, R.color.title_color_one) ) if (boldLastValue == true) { binding.regularTv.typeface = Typeface.DEFAULT_BOLD } - lastValueTypeFace?.let { - binding.regularTv.typeface = it - } + lastValueTypeFace?.let { binding.regularTv.typeface = it } binding.regularTv.textSize = - regularTextStyle?.textSize ?: resources.getInteger(R.integer.font_small) - .toFloat() + regularTextStyle?.textSize ?: resources.getInteger(R.integer.font_small).toFloat() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/fragment/ChoiceBottomSheet.kt b/app/src/main/java/com/naviapp/common/fragment/ChoiceBottomSheet.kt index b7b085ec59..80196ea599 100644 --- a/app/src/main/java/com/naviapp/common/fragment/ChoiceBottomSheet.kt +++ b/app/src/main/java/com/naviapp/common/fragment/ChoiceBottomSheet.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,8 +13,8 @@ import android.view.ViewStub import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import com.navi.common.ui.fragment.BaseBottomSheet -import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler import com.navi.common.utils.observeNonNull +import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.navigator.NaviDeepLinkNavigator @@ -26,12 +26,13 @@ import com.naviapp.personalloan.getloan.mfi.viewmodel.MfiConsentVM import com.naviapp.utils.Constants import dagger.hilt.android.AndroidEntryPoint - @AndroidEntryPoint class ChoiceBottomSheet : BaseBottomSheet() { private lateinit var binding: ChoiceBottomSheetBinding - private val viewModel by lazy { ViewModelProvider(requireActivity()).get(MfiConsentVM::class.java) } + private val viewModel by lazy { + ViewModelProvider(requireActivity()).get(MfiConsentVM::class.java) + } private val naviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.MFIConsent() override fun setContainerView(viewStub: ViewStub) { @@ -65,15 +66,12 @@ class ChoiceBottomSheet : BaseBottomSheet() { private fun moveToNextScreen() { viewModel.mfiConsentResponse.value?.content?.bottomSheetData?.primaryCta?.let { - val bundle = Bundle().apply { - putString(ErrorActivity.IS_SOFT_REJECT, Constants.TRUE) - putString(Constants.WIDGET_ID, Constants.PERSONAL_LOAN) - } - NaviDeepLinkNavigator.navigate( - activity = activity, - ctaData = it, - bundle = bundle - ) + val bundle = + Bundle().apply { + putString(ErrorActivity.IS_SOFT_REJECT, Constants.TRUE) + putString(Constants.WIDGET_ID, Constants.PERSONAL_LOAN) + } + NaviDeepLinkNavigator.navigate(activity = activity, ctaData = it, bundle = bundle) } } @@ -110,4 +108,4 @@ class ChoiceBottomSheet : BaseBottomSheet() { arguments = bundle } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitBottomSheet.kt b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitBottomSheet.kt index 52645cd3f6..c3f30e4042 100644 --- a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitBottomSheet.kt +++ b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitBottomSheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.fragment /* * @@ -32,11 +39,12 @@ class DashboardPolicyBenefitBottomSheet : BaseBottomSheet(), DashboardRadioButto override fun setContainerView(viewStub: ViewStub) { viewStub.layoutResource = R.layout.dashboard_policy_benefit_bottom_sheet binding = DataBindingUtil.getBinding(viewStub.inflate())!! - arguments?.getParcelable(BUNDLE_DATA_KEY) - ?.let { dashboardPolicyBenefitData -> - response = dashboardPolicyBenefitData - initLayout(dashboardPolicyBenefitData, binding) - } ?: safelyDismissDialog() + arguments?.getParcelable(BUNDLE_DATA_KEY)?.let { + dashboardPolicyBenefitData -> + response = dashboardPolicyBenefitData + initLayout(dashboardPolicyBenefitData, binding) + } + ?: safelyDismissDialog() } private fun initLayout( @@ -56,11 +64,16 @@ class DashboardPolicyBenefitBottomSheet : BaseBottomSheet(), DashboardRadioButto response?.actionData?.metaData?.clickedData?.eventName?.let { it1 -> NaviTrackEvent.trackEventOnClickStream( it1, - response?.actionData?.metaData?.clickedData?.parameters?.plus( - mapOf( - POLICY_NUMBER to selectedPolicyBenefitData?.policyId.toString() + response + ?.actionData + ?.metaData + ?.clickedData + ?.parameters + ?.plus( + mapOf( + POLICY_NUMBER to selectedPolicyBenefitData?.policyId.toString() + ) ) - ) ) } policyBenefitBottomSheetListener?.onPolicyBenefitSelected( @@ -72,26 +85,25 @@ class DashboardPolicyBenefitBottomSheet : BaseBottomSheet(), DashboardRadioButto } dashboardPolicyBenefitData.listOfPolicyBenefits?.let { listOfItems -> - binding.rvPolicyBenefit.adapter = DashboardRadioGroupAdapter( - list = listOfItems, - radioButtonListener = this - ) + binding.rvPolicyBenefit.adapter = + DashboardRadioGroupAdapter( + list = listOfItems, + radioButtonListener = this + ) } dashboardPolicyBenefitData.actionData?.title?.let { it1 -> - binding.btnContinue.setProperties( - title = it1 - ) + binding.btnContinue.setProperties(title = it1) } showUI() } private fun showUI() { - binding.apply { - tvTitle.text = resources.getString(R.string.select_policy) - } + binding.apply { tvTitle.text = resources.getString(R.string.select_policy) } } - fun setPolicyBenefitListener(policyBenefitBottomSheetListener: DashboardPolicyBenefitBottomSheetListener) { + fun setPolicyBenefitListener( + policyBenefitBottomSheetListener: DashboardPolicyBenefitBottomSheetListener + ) { this.policyBenefitBottomSheetListener = policyBenefitBottomSheetListener } @@ -101,12 +113,8 @@ class DashboardPolicyBenefitBottomSheet : BaseBottomSheet(), DashboardRadioButto const val TAG = "DashboardPolicyBenefitBottomSheet" const val BUNDLE_DATA_KEY = "BUNDLE_DATA_KEY" - fun getInstance( - bundle: Bundle? = null - ): DashboardPolicyBenefitBottomSheet { - return DashboardPolicyBenefitBottomSheet().apply { - arguments = bundle - } + fun getInstance(bundle: Bundle? = null): DashboardPolicyBenefitBottomSheet { + return DashboardPolicyBenefitBottomSheet().apply { arguments = bundle } } } @@ -114,5 +122,4 @@ class DashboardPolicyBenefitBottomSheet : BaseBottomSheet(), DashboardRadioButto binding.btnContinue.setStateABV(true, R.color.outrageous_orange) selectedPolicyBenefitData = radioButtonModel as? PolicyBenefitData } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitRetryBottomSheet.kt b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitRetryBottomSheet.kt index e597662baf..5a90027461 100644 --- a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitRetryBottomSheet.kt +++ b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyBenefitRetryBottomSheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.fragment import android.view.View @@ -8,13 +15,11 @@ import com.naviapp.R import com.naviapp.common.listeners.DashboardPolicyBenefitRetryListener import com.naviapp.databinding.DashboardPolicyBenefitRetryBinding - class DashboardPolicyBenefitRetryBottomSheet : BaseBottomSheet(), View.OnClickListener { private lateinit var binding: DashboardPolicyBenefitRetryBinding private var policyBenefitRetryBottomSheet: DashboardPolicyBenefitRetryListener? = null - override fun setContainerView(viewStub: ViewStub) { viewStub.layoutResource = R.layout.dashboard_policy_benefit_retry binding = DataBindingUtil.getBinding(viewStub.inflate())!! @@ -51,4 +56,4 @@ class DashboardPolicyBenefitRetryBottomSheet : BaseBottomSheet(), View.OnClickLi fun getInstance() = DashboardPolicyBenefitRetryBottomSheet() } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyPaymentBottomSheet.kt b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyPaymentBottomSheet.kt index 4a88a05872..6c497a1e94 100644 --- a/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyPaymentBottomSheet.kt +++ b/app/src/main/java/com/naviapp/common/fragment/DashboardPolicyPaymentBottomSheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.fragment import android.os.Bundle @@ -8,7 +15,6 @@ import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.CtaData import com.navi.common.ui.fragment.BaseBottomSheet import com.navi.design.utils.setSpannableString - import com.naviapp.R import com.naviapp.common.listeners.DashboardPolicyBenefitRetryListener import com.naviapp.common.navigator.NaviDeepLinkNavigator @@ -21,25 +27,22 @@ import com.naviapp.utils.Constants.POLICY_ID import com.naviapp.utils.Constants.TRUE import com.naviapp.utils.SPACE - class DashboardPolicyPaymentBottomSheet : BaseBottomSheet(), View.OnClickListener { private var binding: DashboardPolicyPaymentBottomSheetBinding? = null private var policyBenefitRetryBottomSheet: DashboardPolicyBenefitRetryListener? = null - override fun setContainerView(viewStub: ViewStub) { viewStub.layoutResource = R.layout.dashboard_policy_payment_bottom_sheet binding = DataBindingUtil.getBinding(viewStub.inflate())!! arguments?.getString(POLICY_ID)?.let { - arguments?.getParcelable(BUNDLE_DATA_KEY) - ?.let { policyPaymentData -> - binding?.let { binding -> - initLayout(policyPaymentData, binding, it) - } - } ?: safelyDismissDialog() - } ?: safelyDismissDialog() - + arguments?.getParcelable(BUNDLE_DATA_KEY)?.let { + policyPaymentData -> + binding?.let { binding -> initLayout(policyPaymentData, binding, it) } + } + ?: safelyDismissDialog() + } + ?: safelyDismissDialog() } fun initLayout( @@ -53,12 +56,13 @@ class DashboardPolicyPaymentBottomSheet : BaseBottomSheet(), View.OnClickListene binding.tvPrimaryAction.apply { text = policyPaymentData?.actionData?.title - val bundle = Bundle().apply { - putString(POLICY_ID, policyId) - putString(IS_INSTALMENT, TRUE) - putString(INSTALMENT_AMOUNT, policyPaymentData?.emi?.amount?.toString()) - putString(INSTALMENT_DATE, policyPaymentData?.installmentDueDate) - } + val bundle = + Bundle().apply { + putString(POLICY_ID, policyId) + putString(IS_INSTALMENT, TRUE) + putString(INSTALMENT_AMOUNT, policyPaymentData?.emi?.amount?.toString()) + putString(INSTALMENT_DATE, policyPaymentData?.installmentDueDate) + } setOnClickListener { safelyDismissDialog() policyPaymentData?.actionData?.metaData?.clickedData?.eventName?.let { it -> @@ -68,9 +72,10 @@ class DashboardPolicyPaymentBottomSheet : BaseBottomSheet(), View.OnClickListene ) } NaviDeepLinkNavigator.navigate( - activity, CtaData( - url = policyPaymentData?.actionData?.url - ), bundle = bundle, finish = false + activity, + CtaData(url = policyPaymentData?.actionData?.url), + bundle = bundle, + finish = false ) } } @@ -86,7 +91,6 @@ class DashboardPolicyPaymentBottomSheet : BaseBottomSheet(), View.OnClickListene policyBenefitRetryBottomSheet?.onRetryClicked() safelyDismissDialog() } - } } @@ -100,12 +104,8 @@ class DashboardPolicyPaymentBottomSheet : BaseBottomSheet(), View.OnClickListene const val TAG = "DashboardPolicyBenefitPaymentBottomSheet" const val BUNDLE_DATA_KEY = "BUNDLE_DATA_KEY" - fun getInstance( - bundle: Bundle? = null - ): DashboardPolicyPaymentBottomSheet { - return DashboardPolicyPaymentBottomSheet().apply { - arguments = bundle - } + fun getInstance(bundle: Bundle? = null): DashboardPolicyPaymentBottomSheet { + return DashboardPolicyPaymentBottomSheet().apply { arguments = bundle } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/fragment/SearchFragmentV2.kt b/app/src/main/java/com/naviapp/common/fragment/SearchFragmentV2.kt index 3131913f27..089ef2d409 100644 --- a/app/src/main/java/com/naviapp/common/fragment/SearchFragmentV2.kt +++ b/app/src/main/java/com/naviapp/common/fragment/SearchFragmentV2.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2021 by Navi Technologies Private Limited + * * Copyright © 2021-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -41,7 +41,9 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR private var currentQuery = Constants.EMPTY private var minCharRequired = 0 private var sharedSearchSharedViewModel: SharedSearchViewModelV2? = null - private val searchViewModel by lazy { ViewModelProvider(this).get(SearchViewModelV2::class.java) } + private val searchViewModel by lazy { + ViewModelProvider(this).get(SearchViewModelV2::class.java) + } private val analyticsEventTracker = NaviAnalytics.naviAnalytics.HomeLoanSearchV2() override fun onCreateView( @@ -55,9 +57,8 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR override fun onAttach(context: Context) { super.onAttach(context) - sharedSearchSharedViewModel = activity?.let { - ViewModelProvider(it).get(SharedSearchViewModelV2::class.java) - } + sharedSearchSharedViewModel = + activity?.let { ViewModelProvider(it).get(SharedSearchViewModelV2::class.java) } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -69,16 +70,11 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR if (data is LabeledTextInputSearchWidgetModel) { var searchApiUrl: String? = null var queryParams = hashMapOf() - data.widgetData?.inputTextSearchItemData?.searchApiDetails?.let { searchApiDetails -> - searchApiDetails.url?.let { - searchApiUrl = it.trimStart('/') - } - searchApiDetails.queryParams?.let { - queryParams = it - } - searchApiDetails.minCharactersRequiredToSearch?.let { - minCharRequired = it - } + data.widgetData?.inputTextSearchItemData?.searchApiDetails?.let { searchApiDetails + -> + searchApiDetails.url?.let { searchApiUrl = it.trimStart('/') } + searchApiDetails.queryParams?.let { queryParams = it } + searchApiDetails.minCharactersRequiredToSearch?.let { minCharRequired = it } } queryParams["pageSize"] = DEFAULT_PAGE_SIZE queryParams["pageNumber"] = DEFAULT_PAGE_NUMBER @@ -86,7 +82,8 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR sharedSearchSharedViewModel?.coroutineScope?.let { coroutineScope -> if (searchApiUrl.isNotNullAndNotEmpty()) { binding.searchWidget.updateData(data, 0, this@SearchFragmentV2) - binding.searchWidget.widgetBinding.plainTextInput.textChanges() + binding.searchWidget.widgetBinding.plainTextInput + .textChanges() .debounce(40) .map { query -> query.toString().trim() } .distinctUntilChanged() @@ -107,9 +104,7 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR } private fun initObservers() { - searchViewModel.searchResponse.observe(viewLifecycleOwner) { - processSearchResponseData(it) - } + searchViewModel.searchResponse.observe(viewLifecycleOwner) { processSearchResponseData(it) } } private fun initUi() { @@ -119,16 +114,18 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR private fun processSearchResponseData(searchResponse: CommonSearchResponse) { searchResponse.content?.let { contentList -> - if (currentQuery.length >= minCharRequired && currentQuery.trim().isNotEmpty() && - contentList.none { it.value.equals(currentQuery, ignoreCase = true) } + if ( + currentQuery.length >= minCharRequired && + currentQuery.trim().isNotEmpty() && + contentList.none { it.value.equals(currentQuery, ignoreCase = true) } ) { val searchRow = CommonSearchRow(id = CUSTOM, value = currentQuery) searchRow.type = ResultType.NO_RESULT - binding.searchWidget.widgetModel.widgetData?.inputTextSearchItemData?.noResultNote?.let { - adapter.updateData(contentList + listOf(searchRow), currentQuery, it) - } ?: run { - adapter.updateData(listOf(searchRow) + contentList, currentQuery) - } + binding.searchWidget.widgetModel.widgetData + ?.inputTextSearchItemData + ?.noResultNote + ?.let { adapter.updateData(contentList + listOf(searchRow), currentQuery, it) } + ?: run { adapter.updateData(listOf(searchRow) + contentList, currentQuery) } } else { adapter.updateData(contentList, currentQuery) } @@ -139,9 +136,7 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR private const val DEFAULT_PAGE_SIZE = "100" private const val DEFAULT_PAGE_NUMBER = "0" fun newInstance(bundle: Bundle?): SearchFragmentV2 { - return SearchFragmentV2().apply { - arguments = bundle - } + return SearchFragmentV2().apply { arguments = bundle } } } @@ -163,4 +158,4 @@ class SearchFragmentV2 : BaseFragment(), WidgetCallback, BackListener, PropertyR sharedSearchSharedViewModel?.setSelectedSearchItem(selectedRow) activity?.supportFragmentManager?.popBackStackImmediate() } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/listeners/DashboardRadioButtonListener.kt b/app/src/main/java/com/naviapp/common/listeners/DashboardRadioButtonListener.kt index 9c3e0f1de8..144260f41f 100644 --- a/app/src/main/java/com/naviapp/common/listeners/DashboardRadioButtonListener.kt +++ b/app/src/main/java/com/naviapp/common/listeners/DashboardRadioButtonListener.kt @@ -1,5 +1,12 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.listeners interface DashboardRadioButtonListener { fun onRadioButtonTap(radioButtonModel: RadioButtonModel) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/listeners/RadioButtonModel.kt b/app/src/main/java/com/naviapp/common/listeners/RadioButtonModel.kt index d0b9204224..024d3f1966 100644 --- a/app/src/main/java/com/naviapp/common/listeners/RadioButtonModel.kt +++ b/app/src/main/java/com/naviapp/common/listeners/RadioButtonModel.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.listeners interface RadioButtonModel { @@ -6,4 +13,4 @@ interface RadioButtonModel { fun setSelectedState(selected: Boolean) { this.selected = selected } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/navigator/NaviDeepLinkNavigator.kt b/app/src/main/java/com/naviapp/common/navigator/NaviDeepLinkNavigator.kt index 755fbccc0d..cc18dfa0e0 100644 --- a/app/src/main/java/com/naviapp/common/navigator/NaviDeepLinkNavigator.kt +++ b/app/src/main/java/com/naviapp/common/navigator/NaviDeepLinkNavigator.kt @@ -26,12 +26,20 @@ import com.navi.chat.models.NaviChatSystemLocalData import com.navi.chat.ui.activities.NaviChatActivity import com.navi.chat.utils.* import com.navi.common.applicationplatform.ui.ApplicationPlatformActivity +import com.navi.common.BuildConfig import com.navi.common.deeplink.listener.DeepLinkListener import com.navi.common.utils.log import com.navi.common.utils.orFalse import com.navi.common.utils.orZero import com.navi.common.utils.toActionData +import com.navi.common.utils.toActionData +import com.navi.common.video.NaviYoutubeActivity import com.navi.insurance.navigator.NaviInsuranceDeeplinkNavigator +import com.navi.naviwidgets.utils.CHOOSER_TITLE_PARAM +import com.navi.naviwidgets.utils.EMAIL_BODY_PARAM +import com.navi.naviwidgets.utils.EMAIL_ID_PARAM +import com.navi.naviwidgets.utils.EMAIL_SUBJECT_PARAM +import com.navi.insurance.util.VIDEO_ID_EXTRA import com.naviapp.R import com.naviapp.appupdate.activities.UpdateAppActivity import com.naviapp.custom_payments.CustomPaymentActivity @@ -43,6 +51,7 @@ import com.naviapp.dashboard.menu.loans.activity.AllLoanDetailsActivity import com.naviapp.dashboard.menu.notificationsettings.NotificationSettingsActivity import com.naviapp.dashboard.menu.utils.INSURANCE import com.naviapp.dashboard.menu.utils.openCallDialScreen +import com.naviapp.dashboard.menu.utils.openEmailScreenWithSubjectAndBody import com.naviapp.dashboard.newloan.NewLoanConsentActivity import com.naviapp.dashboard.rating.RatingActivity import com.naviapp.email.activity.EmailActivity @@ -65,6 +74,7 @@ import com.naviapp.payment.activities.NaviPaymentActivity import com.naviapp.permission.activities.PermissionActivity import com.naviapp.personalloan.getloan.activities.* import com.naviapp.personalloan.getloan.bankdetailsautodebit.view.activities.EnachTutorialActivity +import com.naviapp.personalloan.getloan.common.fragment.CustomerSupportFragment import com.naviapp.personalloan.getloan.summary.activities.LoanAgreementActivity import com.naviapp.personalloan.insurance.activity.InsuranceAddOnActivity import com.naviapp.personalloan.insurance.activity.InsuranceDetailActivity @@ -91,9 +101,9 @@ import com.naviapp.utils.Constants.URL import com.naviapp.utils.ShareUtil import com.naviapp.utils.openPlayStore import com.naviapp.utils.openWhatsAppChatConversation -import java.io.ByteArrayOutputStream import kotlinx.coroutines.ExperimentalCoroutinesApi import timber.log.Timber +import java.io.ByteArrayOutputStream @ExperimentalCoroutinesApi object NaviDeepLinkNavigator : DeepLinkListener { @@ -178,9 +188,12 @@ object NaviDeepLinkNavigator : DeepLinkListener { const val SKIP_MANDATE_V2 = "SKIP_MANDATE_V2" private const val STORY = "story" private const val WEB_URL = "webUrl" + private const val CUSTOMER_SUPPORT = "CUSTOMER_SUPPORT" const val DOCUMENT_LIST = "documentList" + const val OPEN_EMAIL = "openEmail" const val SURVEY = "SURVEY" private const val APP_PLATFORM = "applicationPlatform" + private const val VIEW_VIDEO = "view_video" fun navigate( activity: Activity?, @@ -232,6 +245,9 @@ object NaviDeepLinkNavigator : DeepLinkListener { Intent(activity, GetLoanV2Activity::class.java) } } + OPEN_EMAIL -> { + openEmailFromCta(activity, ctaData) + } ENACH_TUTORIAL_ACTIVITY_V2 -> { intent = Intent(activity, EnachTutorialV2Activity::class.java) } @@ -428,15 +444,15 @@ object NaviDeepLinkNavigator : DeepLinkListener { source = shareableLink.orEmpty(), sourceId = sourceId.orEmpty(), currentUserName = - PreferenceManager.getObjectPrefrences( - Constants.CURRENT_USER, - UserDetail::class.java - ) - ?.name - .orEmpty(), + PreferenceManager.getObjectPrefrences( + Constants.CURRENT_USER, + UserDetail::class.java + ) + ?.name + .orEmpty(), externalCustomerId = - PreferenceManager.getStringPreference(USER_EXTERNAL_ID) - .orEmpty(), + PreferenceManager.getStringPreference(USER_EXTERNAL_ID) + .orEmpty(), isFromNotification = isFromNotification, shouldShowCsat = shouldShowCsat, csatConversationId = csatConversationId @@ -498,6 +514,16 @@ object NaviDeepLinkNavigator : DeepLinkListener { } } } + CUSTOMER_SUPPORT -> { + (activity as? AppCompatActivity)?.let { + val lineItem = + ctaData.parameters + ?.filter { it.key?.equals("screen") ?: false } + ?.first() + CustomerSupportFragment.newInstance(lineItem?.value ?: "", "") + .show(it.supportFragmentManager, CustomerSupportFragment.TAG) + } + } SHARE_APP, HOME_SHARE_APP -> { var shareableLink: String? = null @@ -569,6 +595,20 @@ object NaviDeepLinkNavigator : DeepLinkListener { APP_PLATFORM -> { intent = Intent(activity, ApplicationPlatformActivity::class.java) } + VIEW_VIDEO -> { + var videoId: String? = null + ctaData.parameters?.forEach { lineItem -> + when (lineItem.key) { + VIDEO_ID_EXTRA -> videoId = lineItem.value ?: "" + } + } + intent = Intent(activity, NaviYoutubeActivity::class.java) + bundle.putString(com.navi.common.utils.Constants.KEY_VIDEO_ID, videoId) + bundle.putString( + com.navi.common.utils.Constants.KEY_API_KEY, + BuildConfig.YOUTUBE_KEY + ) + } } ctaData.parameters?.forEach { keyValue -> bundle.putString(keyValue.key, keyValue.value) @@ -579,8 +619,8 @@ object NaviDeepLinkNavigator : DeepLinkListener { intent.putExtra(Constants.SUB_REDIRECT, thirdIdentifier) if ( clearTask.orFalse() || - firstIdentifier == HOME_SMALL || - firstIdentifier == HOME + firstIdentifier == HOME_SMALL || + firstIdentifier == HOME ) { intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK or @@ -611,6 +651,34 @@ object NaviDeepLinkNavigator : DeepLinkListener { } } + private fun openEmailFromCta(activity: Activity?, ctaData: CtaData) { + try { + var emailId: String? = null + var subject: String? = null + var body: String? = null + var chooserTitle: String? = null + ctaData.parameters?.forEach { + when (it.key) { + EMAIL_ID_PARAM -> emailId = it.value + EMAIL_SUBJECT_PARAM -> subject = it.value + EMAIL_BODY_PARAM -> body = it.value + CHOOSER_TITLE_PARAM -> chooserTitle = it.value + } + } + activity?.let { + openEmailScreenWithSubjectAndBody( + it, + customerSupportEmail = emailId, + subject = subject, + body = body, + chooserTitle = chooserTitle + ) + } + } catch (e: Exception) { + e.log() + } + } + override fun navigateTo( activity: Activity?, ctaData: CtaData, diff --git a/app/src/main/java/com/naviapp/common/navigator/ScreenNavigator.kt b/app/src/main/java/com/naviapp/common/navigator/ScreenNavigator.kt index a8100fed48..280d7ac478 100644 --- a/app/src/main/java/com/naviapp/common/navigator/ScreenNavigator.kt +++ b/app/src/main/java/com/naviapp/common/navigator/ScreenNavigator.kt @@ -1,6 +1,7 @@ /* - * * - * * Copyright (c) 2020 . All rights reserved @Navi + * + * * Copyright © 2020-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -51,42 +52,40 @@ class ScreenNavigator { ) { activity?.let { act -> if (act.isDestroyed || act.isFinishing) return - val intent = when (page) { - RATING_SCREEN -> Intent(activity, RatingActivity::class.java) - FAQS_SCREEN -> Intent(activity, FaqsActivity::class.java) - LOAN_AGREEMENT_SCREEN -> Intent(activity, LoanAgreementActivity::class.java) - PageStatusType.OFFER_GENERATION -> Intent( - activity, - NewLoanConsentActivity::class.java - ) - LOAN_ELIGIBLE_SCREEN -> Intent(activity, LoanEligibilityLoaderActivity::class.java) - MY_LOAN_SCREEN -> Intent(activity, AllLoanDetailsActivity::class.java) - PageStatusType.LOAN_APPLICATION -> { - if (subPage == SubPageStatusType.DISBURSEMENT_STATUS) { - Intent(activity, LoanDisbursementLoaderActivity::class.java) - } else { - Intent(activity, GetLoanActivity::class.java) + val intent = + when (page) { + RATING_SCREEN -> Intent(activity, RatingActivity::class.java) + FAQS_SCREEN -> Intent(activity, FaqsActivity::class.java) + LOAN_AGREEMENT_SCREEN -> Intent(activity, LoanAgreementActivity::class.java) + PageStatusType.OFFER_GENERATION -> + Intent(activity, NewLoanConsentActivity::class.java) + LOAN_ELIGIBLE_SCREEN -> + Intent(activity, LoanEligibilityLoaderActivity::class.java) + MY_LOAN_SCREEN -> Intent(activity, AllLoanDetailsActivity::class.java) + PageStatusType.LOAN_APPLICATION -> { + if (subPage == SubPageStatusType.DISBURSEMENT_STATUS) { + Intent(activity, LoanDisbursementLoaderActivity::class.java) + } else { + Intent(activity, GetLoanActivity::class.java) + } } - } - NaviDeepLinkNavigator.LOAN_APPLICATION_V2 -> { - if (subPage == NaviDeepLinkNavigator.DISBURSEMENT_STATUS_V2) { - Intent(activity, LoanDisbursementLoaderV2Activity::class.java) - } else { - Intent(activity, GetLoanV2Activity::class.java) + NaviDeepLinkNavigator.LOAN_APPLICATION_V2 -> { + if (subPage == NaviDeepLinkNavigator.DISBURSEMENT_STATUS_V2) { + Intent(activity, LoanDisbursementLoaderV2Activity::class.java) + } else { + Intent(activity, GetLoanV2Activity::class.java) + } } + INSURANCE_DETAIL_SCREEN -> Intent(activity, InsuranceDetailActivity::class.java) + NAVI_WEB_VIEW -> Intent(activity, NaviWebViewActivity::class.java) + REGISTRATION_SCREEN -> Intent(activity, RegistrationActivity::class.java) + EMAIL_US_SCREEN -> Intent(activity, EmailActivity::class.java) + POST_OFFER_GENERATION -> Intent(activity, GetLoanActivity::class.java) + else -> null } - INSURANCE_DETAIL_SCREEN -> Intent(activity, InsuranceDetailActivity::class.java) - NAVI_WEB_VIEW -> Intent(activity, NaviWebViewActivity::class.java) - REGISTRATION_SCREEN -> Intent(activity, RegistrationActivity::class.java) - EMAIL_US_SCREEN -> Intent(activity, EmailActivity::class.java) - POST_OFFER_GENERATION -> Intent(activity, GetLoanActivity::class.java) - else -> null - } intent?.let { it.putExtra(Constants.REDIRECT_STATUS, subPage) - bundle?.apply { - it.putExtras(this) - } + bundle?.apply { it.putExtras(this) } when { isResultActivity.orFalse() -> { act.startActivityForResult(it, requestCode.orZero()) @@ -145,19 +144,19 @@ class ScreenNavigator { intent = Intent(currentActivity, SkipMandateActivity::class.java) } LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN -> { - intent = Intent( - currentActivity, LoanDisbursementProductPlacementActivity::class.java - ) + intent = + Intent( + currentActivity, + LoanDisbursementProductPlacementActivity::class.java + ) } CROSS_SELL_SCREEN -> { intent = Intent(currentActivity, CrossSellActivity::class.java) } - INTERMEDIATE_SCREEN -> intent = - Intent(currentActivity, IntermediateActivity::class.java) - - INTERMEDIATE_SCREEN_V2 -> intent = - Intent(currentActivity, IntermediateV2Activity::class.java) - + INTERMEDIATE_SCREEN -> + intent = Intent(currentActivity, IntermediateActivity::class.java) + INTERMEDIATE_SCREEN_V2 -> + intent = Intent(currentActivity, IntermediateV2Activity::class.java) HOME_LOAN_STATUS_TRACKER -> { intent = Intent(currentActivity, HomeLoanTrackerActivity::class.java) } @@ -166,18 +165,17 @@ class ScreenNavigator { } } intent?.let { - bundle?.apply { - it.putExtras(this) - } + bundle?.apply { it.putExtras(this) } it.addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK or + FLAG_ACTIVITY_CLEAR_TASK or + Intent.FLAG_ACTIVITY_CLEAR_TOP ) currentActivity.startActivity(it) currentActivity.finish() return } } - } private object Holder { @@ -214,4 +212,4 @@ class ScreenNavigator { val instance: ScreenNavigator by lazy { Holder.INSTANCE } const val REWARDS_DELIGHT_SCREEN = "REWARDS_DELIGHT_SCREEN" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/transformer/HLLatencyMapper.kt b/app/src/main/java/com/naviapp/common/transformer/HLLatencyMapper.kt index bfcb507080..7f48b9c398 100644 --- a/app/src/main/java/com/naviapp/common/transformer/HLLatencyMapper.kt +++ b/app/src/main/java/com/naviapp/common/transformer/HLLatencyMapper.kt @@ -9,10 +9,12 @@ class HLLatencyMapper(screenName: String) : LatencyMapper(screenName) { private var loanApplicationId: String = EMPTY private var loanType: String = EMPTY + private var eventName: String? = null @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun trackScreenTime() { analyticsTracker.timeSpendOnScreen( + eventName, screenName, loanApplicationId, loanType, @@ -20,8 +22,9 @@ class HLLatencyMapper(screenName: String) : LatencyMapper(screenName) { ) } - fun setData(loanApplicationId: String?, loanType: String?) { + fun setData(loanApplicationId: String?, loanType: String?, eventName: String? = null) { this.loanApplicationId = loanApplicationId.orEmpty() this.loanType = loanType.orEmpty() + this.eventName = eventName } } \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/common/viewholders/DashboardPolicyBenefitVH.kt b/app/src/main/java/com/naviapp/common/viewholders/DashboardPolicyBenefitVH.kt index 17637be56a..50530e95ca 100644 --- a/app/src/main/java/com/naviapp/common/viewholders/DashboardPolicyBenefitVH.kt +++ b/app/src/main/java/com/naviapp/common/viewholders/DashboardPolicyBenefitVH.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.common.viewholders import androidx.core.content.ContextCompat @@ -16,7 +23,6 @@ import com.naviapp.models.PolicyBenefitData import com.naviapp.models.PolicyBenefitStatus import com.naviapp.utils.decimalFormat - class DashboardPolicyBenefitVH(private val viewBinding: ViewDataBinding) : RadioBaseViewHolder(viewBinding.root) { @@ -28,54 +34,58 @@ class DashboardPolicyBenefitVH(private val viewBinding: ViewDataBinding) : ) { if (viewBinding is LayoutDashboardPolicyBenefitWidgetBinding) { viewBinding.apply { - tvPolicyNumber.text = String.format( - viewBinding.root.context.getString(R.string.policy_number), - model.policyId - ) - tvPolicySumInsured.text = String.format( - itemView.context.getString(R.string.policy_sum_insured), - decimalFormat.format(model.sumInsured) - ) - model.numberOfMembersInsured?.let { - tvPolicyTotalInsured.text = String.format( - itemView.context.getString( - if (it > 1) R.string.policy_members_total_insured - else - R.string.policy_member_total_insured - ), - model.numberOfMembersInsured + tvPolicyNumber.text = + String.format( + viewBinding.root.context.getString(R.string.policy_number), + model.policyId ) + tvPolicySumInsured.text = + String.format( + itemView.context.getString(R.string.policy_sum_insured), + decimalFormat.format(model.sumInsured) + ) + model.numberOfMembersInsured?.let { + tvPolicyTotalInsured.text = + String.format( + itemView.context.getString( + if (it > 1) R.string.policy_members_total_insured + else R.string.policy_member_total_insured + ), + model.numberOfMembersInsured + ) } - setExtras( - model - ) - if (model.status == PolicyBenefitStatus.ACTIVE.name || model.status == PolicyBenefitStatus.GRACE_PERIOD.name) { + setExtras(model) + if ( + model.status == PolicyBenefitStatus.ACTIVE.name || + model.status == PolicyBenefitStatus.GRACE_PERIOD.name + ) { radioBtn.isChecked = model.getSelectedState() if (model.getSelectedState()) { - clParent.background = ContextCompat.getDrawable( - itemView.context, - R.drawable.rounded_rectangle_orange_border - ) + clParent.background = + ContextCompat.getDrawable( + itemView.context, + R.drawable.rounded_rectangle_orange_border + ) } else { - clParent.background = ContextCompat.getDrawable( - itemView.context, - R.drawable.rounded_rectangle_grey_border_8dp_radius - ) + clParent.background = + ContextCompat.getDrawable( + itemView.context, + R.drawable.rounded_rectangle_grey_border_8dp_radius + ) } clickHandle(active = true) } else { - clParent.background = ContextCompat.getDrawable( - itemView.context, - R.drawable.rounded_rectangle_grey_border_8dp_radius - ) + clParent.background = + ContextCompat.getDrawable( + itemView.context, + R.drawable.rounded_rectangle_grey_border_8dp_radius + ) clickHandle(active = false) } } - itemView.setOnClickListener { - action.invoke(position) - } + itemView.setOnClickListener { action.invoke(position) } } } @@ -84,46 +94,52 @@ class DashboardPolicyBenefitVH(private val viewBinding: ViewDataBinding) : viewBinding.apply { clParent.isClickable = active clParent.isEnabled = active - radioBtn.buttonDrawable = if (active) { - ContextCompat.getDrawable( - itemView.context, - R.drawable.radio_button_selector_grey - ) - } else { - ContextCompat.getDrawable( - itemView.context, - R.drawable.ic_blocked_radio_button - ) - } + radioBtn.buttonDrawable = + if (active) { + ContextCompat.getDrawable( + itemView.context, + R.drawable.radio_button_selector_grey + ) + } else { + ContextCompat.getDrawable( + itemView.context, + R.drawable.ic_blocked_radio_button + ) + } } } } - private fun setExtras( - policyBenefitData: PolicyBenefitData? = null + private fun setExtras(policyBenefitData: PolicyBenefitData? = null) { - ) { if (viewBinding is LayoutDashboardPolicyBenefitWidgetBinding) { if (policyBenefitData?.statusAttribute?.title.isNotNull()) { - viewBinding.tvBenefitError.setSpannableString(policyBenefitData?.statusAttribute?.title) + viewBinding.tvBenefitError.setSpannableString( + policyBenefitData?.statusAttribute?.title + ) viewBinding.benefitErrorLayout.apply { isVisible = true - background = getNaviDrawable( - radii = CornerRadius( - leftTop = resources.getDimension(R.dimen.layout_dp_0), - rightTop = resources.getDimension(R.dimen.layout_dp_0), - rightBottom = resources.getDimension(R.dimen.layout_dp_8), - leftBottom = resources.getDimension(R.dimen.layout_dp_8) - ), - backgroundColor = policyBenefitData?.statusAttribute?.bgColor?.parseColorSafe() - ) + background = + getNaviDrawable( + radii = + CornerRadius( + leftTop = resources.getDimension(R.dimen.layout_dp_0), + rightTop = resources.getDimension(R.dimen.layout_dp_0), + rightBottom = resources.getDimension(R.dimen.layout_dp_8), + leftBottom = resources.getDimension(R.dimen.layout_dp_8) + ), + backgroundColor = + policyBenefitData?.statusAttribute?.bgColor?.parseColorSafe() + ) } - viewBinding.ivLeftIcon.showWhenDataIsAvailable(policyBenefitData?.statusAttribute?.iconCode) + viewBinding.ivLeftIcon.showWhenDataIsAvailable( + policyBenefitData?.statusAttribute?.iconCode + ) + } else { viewBinding.benefitErrorLayout.isVisible = false } } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/common/viewholders/RadioBaseViewHolder.kt b/app/src/main/java/com/naviapp/common/viewholders/RadioBaseViewHolder.kt index 25e80da052..c031de9fc0 100644 --- a/app/src/main/java/com/naviapp/common/viewholders/RadioBaseViewHolder.kt +++ b/app/src/main/java/com/naviapp/common/viewholders/RadioBaseViewHolder.kt @@ -1,12 +1,18 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + + package com.naviapp.common.viewholders import android.view.View import androidx.recyclerview.widget.RecyclerView import com.naviapp.common.listeners.DashboardRadioButtonListener -import com.naviapp.common.listeners.RadioButtonListener import com.naviapp.common.listeners.RadioButtonModel - abstract class RadioBaseViewHolder(view: View) : RecyclerView.ViewHolder(view) { @@ -16,4 +22,5 @@ abstract class RadioBaseViewHolder(view: View) : radioButtonListener: DashboardRadioButtonListener, action: (position: Int) -> Unit ) -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/naviapp/crosssell/models/CrossSellResponse.kt b/app/src/main/java/com/naviapp/crosssell/models/CrossSellResponse.kt index 5377de0dab..dd20c8d6ff 100644 --- a/app/src/main/java/com/naviapp/crosssell/models/CrossSellResponse.kt +++ b/app/src/main/java/com/naviapp/crosssell/models/CrossSellResponse.kt @@ -11,8 +11,11 @@ package com.naviapp.crosssell.models import com.google.gson.annotations.SerializedName import com.navi.naviwidgets.models.NaviWidget +import com.naviapp.models.response.Header data class CrossSellResponse( + @SerializedName("headerContent") + val header: Header? = null, @SerializedName("contentWidget") val contentWidget: List? = null, @SerializedName("footerWidget") diff --git a/app/src/main/java/com/naviapp/crosssell/ui/CrossSellActivity.kt b/app/src/main/java/com/naviapp/crosssell/ui/CrossSellActivity.kt index c3899b1cad..da8740928c 100644 --- a/app/src/main/java/com/naviapp/crosssell/ui/CrossSellActivity.kt +++ b/app/src/main/java/com/naviapp/crosssell/ui/CrossSellActivity.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -19,17 +17,21 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.navi.base.model.CtaData import com.navi.base.model.GenericAnalyticsData import com.navi.base.model.NaviClickAction +import com.navi.base.model.NaviWidgetClickWithActionData import com.navi.base.sharedpref.PreferenceManager import com.navi.common.model.ModuleNameV2 import com.navi.common.ui.activity.BaseActivity import com.navi.common.utils.observeNonNull +import com.navi.common.utils.toCtaData import com.navi.naviwidgets.actions.DismissFeedback import com.navi.naviwidgets.actions.InformationWidgetCloseClickAction import com.navi.naviwidgets.actions.NavigateClickAction import com.navi.naviwidgets.adapters.NaviAdapter import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.naviwidgets.models.ActionButtonWidget import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.models.PostDisbursalSuccessWidget import com.navi.naviwidgets.models.WidgetChangedData import com.navi.naviwidgets.models.response.InformationWidget import com.navi.naviwidgets.models.response.NpsWidget @@ -41,6 +43,7 @@ import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.analytics.utils.NaviAnalytics.Companion.CROSS_SELL_LAND_SCREEN_EVENT_NAME import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.crosssell.listeners.FeedbackEventListener +import com.naviapp.crosssell.models.CrossSellResponse import com.naviapp.crosssell.viewmodel.CrossSellVM import com.naviapp.databinding.ActivityCrossSellBinding import com.naviapp.home.analytics.LandingScreenAnalytics @@ -54,38 +57,25 @@ import dagger.hilt.android.AndroidEntryPoint class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener { private lateinit var binding: ActivityCrossSellBinding + private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() private val naviAdapter by lazy { - NaviAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) - } - private val crossSellVM by lazy { - ViewModelProvider(this).get(CrossSellVM::class.java) + NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) } + private val crossSellVM by lazy { ViewModelProvider(this).get(CrossSellVM::class.java) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView( - this, - R.layout.activity_cross_sell - ) + binding = DataBindingUtil.setContentView(this, R.layout.activity_cross_sell) setContentView(binding.root) initUI() overridePendingTransition(R.anim.activity_bottom_to_top_slide, R.anim.nothing) initObserver() initError( viewModel = crossSellVM, - dialogDismissClicked = { - fetchCrossSell() - }, + dialogDismissClicked = { fetchCrossSell() }, showFullScreenError = true ) - widgetAnalytics( - GenericAnalyticsData( - eventName = CROSS_SELL_LAND_SCREEN_EVENT_NAME - ) - ) + widgetAnalytics(GenericAnalyticsData(eventName = CROSS_SELL_LAND_SCREEN_EVENT_NAME)) fetchCrossSell() } @@ -101,19 +91,32 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener private fun initUI() { binding.rvCrossSellItems.apply { layoutManager = - LinearLayoutManager( - this@CrossSellActivity, - LinearLayoutManager.VERTICAL, - false - ) + LinearLayoutManager(this@CrossSellActivity, LinearLayoutManager.VERTICAL, false) adapter = naviAdapter } } + private fun processHeader(response: CrossSellResponse?) { + response?.header?.let { header -> + binding.backBtn.showWhenDataIsAvailable(header.leftIconData?.iconCode) + binding.backBtn.setOnClickListener { + NaviDeepLinkNavigator.navigate( + activity = this, + ctaData = CtaData( + url = header.leftIconData?.actionData?.url, + parameters = header.leftIconData?.actionData?.parameters + ), + finish = true + ) + } + } + } + private fun initObserver() { lifecycleScope.launchWhenResumed { crossSellVM.crossSellResponse.observeNonNull(this@CrossSellActivity) { crossSellResponse -> - stopShimmer() + stopShimmer(crossSellResponse) + processHeader(crossSellResponse) crossSellResponse.contentWidget?.let { contentWidgets -> naviAdapter.list = contentWidgets } @@ -123,7 +126,9 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener val actionButtonWidget = footerWidget[0] as ActionButtonWidget text = actionButtonWidget.widgetData?.actionData?.title setOnClickListener { - widgetAnalytics(actionButtonWidget.widgetData?.actionData?.metaData?.clickedData) + widgetAnalytics( + actionButtonWidget.widgetData?.actionData?.metaData?.clickedData + ) onClick( NavigateClickAction( url = actionButtonWidget.widgetData?.actionData?.url, @@ -141,24 +146,28 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener override fun onClick(naviClickAction: NaviClickAction) { when (naviClickAction) { is InformationWidgetCloseClickAction -> { - naviAdapter.removeSameIndexItemTwice( - naviClickAction.position - ) + naviAdapter.removeSameIndexItemTwice(naviClickAction.position) } is NavigateClickAction -> { NaviDeepLinkNavigator.navigate( activity = this, - ctaData = CtaData( - url = naviClickAction.url, - parameters = naviClickAction.parameters - ), + ctaData = + CtaData(url = naviClickAction.url, parameters = naviClickAction.parameters), finish = naviClickAction.isFinishActivity ) } + is NaviWidgetClickWithActionData -> { + naviClickAction.actionData?.let { + widgetNaviAnalyticsEventTracker.onWidgetClickEvent(it) + NaviDeepLinkNavigator.navigate( + this, + it.toCtaData() + ) + } + } is NpsWidgetData -> { - val postDisbursalFeedbackBottomSheet = PostDisbursalFeedbackBottomSheet.newInstance( - naviClickAction, this - ) + val postDisbursalFeedbackBottomSheet = + PostDisbursalFeedbackBottomSheet.newInstance(naviClickAction, this) safelyShowBottomSheet( postDisbursalFeedbackBottomSheet, PostDisbursalFeedbackBottomSheet.TAG @@ -175,10 +184,7 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener override fun widgetAnalytics(genericAnalyticsData: GenericAnalyticsData?) { genericAnalyticsData?.let { data -> - LandingScreenAnalytics.sendEventsToClickStream( - data.eventName, - data.parameters - ) + LandingScreenAnalytics.sendEventsToClickStream(data.eventName, data.parameters) } } @@ -187,13 +193,24 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener naviAdapter.removeSameIndexItemTwice(index = 1) } var npsWidgetIndex = 0 + var isPostDisbursalSuccessWidget = false naviAdapter.list.forEachIndexed { index, _ -> if (naviAdapter.list[index] is NpsWidget) { npsWidgetIndex = index } + if (naviAdapter.list[index] is PostDisbursalSuccessWidget) { + isPostDisbursalSuccessWidget = true + } + } + if (isPostDisbursalSuccessWidget) { + naviAdapter.removeSameIndexItemTwice(index = npsWidgetIndex - 1) } naviAdapter.removeSameIndexItemTwice(index = npsWidgetIndex) - naviAdapter.insertNewItemAtIndex(1, listOfWidgets) + if (isPostDisbursalSuccessWidget) { + naviAdapter.insertNewItemAtIndex(0, listOfWidgets) + } else { + naviAdapter.insertNewItemAtIndex(1, listOfWidgets) + } binding.rvCrossSellItems.scrollToPosition(0) } @@ -204,17 +221,18 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener binding.tvAction.isVisible = false } - private fun stopShimmer() { + private fun stopShimmer(crossSellResponse: CrossSellResponse?) { binding.shimmerLayout.stopShimmer() + crossSellResponse?.header?.let { + binding.headerView.isVisible = true + } binding.shimmerLayout.isVisible = false binding.rvCrossSellItems.isVisible = true binding.tvAction.isVisible = true } override fun submitBottomSheet(submitSurveyResponse: SubmitSurveyResponse) { - submitSurveyResponse.contentWidget?.let { naviWidgets -> - updateWidgets(naviWidgets) - } + submitSurveyResponse.contentWidget?.let { naviWidgets -> updateWidgets(naviWidgets) } } override fun dismissBottomSheet(npsWidgetData: NpsWidgetData?) { @@ -234,4 +252,4 @@ class CrossSellActivity : BaseActivity(), WidgetCallback, FeedbackEventListener override val moduleName: ModuleNameV2 get() = ModuleNameV2.COMMON -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/activities/TrancheDisbursalActivity.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/activities/TrancheDisbursalActivity.kt index 0e9fb78bc6..37da88afda 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/activities/TrancheDisbursalActivity.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/activities/TrancheDisbursalActivity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.dashboard.loanapplicationdetails.activities import android.os.Bundle @@ -35,13 +42,13 @@ class TrancheDisbursalActivity : BaseActivity(), FragmentInteractionListener { val fragment = supportFragmentManager.findFragmentByTag(tag) ?: getFragment(screen, bundle) fragment?.let { fragment.arguments = bundle - supportFragmentManager.takeIf { !it.isStateSaved && !it.isDestroyed } + supportFragmentManager + .takeIf { !it.isStateSaved && !it.isDestroyed } ?.beginTransaction() ?.replace(R.id.container, fragment, tag) ?.commitAllowingStateLoss() - } ?: run { - NaviDeepLinkNavigator.navigate(this, CtaData(url = screen), true) } + ?: run { NaviDeepLinkNavigator.navigate(this, CtaData(url = screen), true) } } private fun getTag(screen: String): String { @@ -53,11 +60,10 @@ class TrancheDisbursalActivity : BaseActivity(), FragmentInteractionListener { fun getFragment(screen: String, bundle: Bundle? = null): Fragment? { return (when (screen) { - REQUEST_INSTALLMENT_SCREEN -> RequestInstallmentFragment() - else -> null - })?.apply { - arguments = bundle - } + REQUEST_INSTALLMENT_SCREEN -> RequestInstallmentFragment() + else -> null + }) + ?.apply { arguments = bundle } } override fun onActivityCompleted(screen: String?, bundle: Bundle?) {} @@ -71,5 +77,4 @@ class TrancheDisbursalActivity : BaseActivity(), FragmentInteractionListener { companion object { const val REQUEST_INSTALLMENT_SCREEN = "REQUEST_INSTALLMENT_SCREEN" } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/details/models/LoanDetailsBinder.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/details/models/LoanDetailsBinder.kt index 60a07c65fe..aa4fca1b8e 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/details/models/LoanDetailsBinder.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/details/models/LoanDetailsBinder.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -10,7 +10,6 @@ package com.naviapp.dashboard.loanapplicationdetails.details.models import com.naviapp.dashboard.loanapplicationdetails.models.BankDetails import com.naviapp.dashboard.loanapplicationdetails.models.CoApplicant - data class LoanDetailsBinder( val loanAccountNumber: String? = null, val loanAmount: String? = null, @@ -26,4 +25,4 @@ data class LoanDetailsBinder( val insurancePremium: String? = null, val emiHoliday: String? = null, val enableInstallmentRequest: Boolean? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentDetails.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentDetails.kt index 59b3564537..f9d0b9070a 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentDetails.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentDetails.kt @@ -1,14 +1,17 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.dashboard.loanapplicationdetails.models import com.google.gson.annotations.SerializedName data class RequestInstallmentDetails( - @SerializedName("amount") - val amount: Double? = null, - @SerializedName("installmentDate") - val installmentDate: Long? = null, - @SerializedName("loanApplicationId") - val loanApplicationId: String? = null, - @SerializedName("demandLetterReferenceIds") - val demandLetters: List? = null + @SerializedName("amount") val amount: Double? = null, + @SerializedName("installmentDate") val installmentDate: Long? = null, + @SerializedName("loanApplicationId") val loanApplicationId: String? = null, + @SerializedName("demandLetterReferenceIds") val demandLetters: List? = null ) diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentResponse.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentResponse.kt index e5370527fe..0981ac4c2a 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentResponse.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/RequestInstallmentResponse.kt @@ -1,13 +1,17 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.dashboard.loanapplicationdetails.models import com.google.gson.annotations.SerializedName import com.navi.naviwidgets.models.response.TextFieldData data class RequestInstallmentResponse( - @SerializedName("title") - val title: TextFieldData, - @SerializedName("subTitle") - val subTitle: TextFieldData, - @SerializedName("description") - val description: TextFieldData + @SerializedName("title") val title: TextFieldData, + @SerializedName("subTitle") val subTitle: TextFieldData, + @SerializedName("description") val description: TextFieldData ) diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/TrancheDocData.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/TrancheDocData.kt index 543a4ba409..bcd772be45 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/TrancheDocData.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/models/TrancheDocData.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.dashboard.loanapplicationdetails.models import com.naviapp.homeloandigital.common.models.HlSelectedFileData @@ -9,5 +16,7 @@ data class TrancheDocData( ) enum class UploadStatus { - UPLOADING, UPLOADED, FILE_TOO_LARGE + UPLOADING, + UPLOADED, + FILE_TOO_LARGE } diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/repositories/TrancheDisbursalRepository.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/repositories/TrancheDisbursalRepository.kt index 156b04eea5..1fd26d2cfd 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/repositories/TrancheDisbursalRepository.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/repositories/TrancheDisbursalRepository.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.dashboard.loanapplicationdetails.repositories import com.navi.common.model.RepoResult @@ -14,11 +15,11 @@ import com.naviapp.network.retrofit.ResponseCallback import com.naviapp.utils.retrofitService import javax.inject.Inject -class TrancheDisbursalRepository -@Inject -constructor() : ResponseCallback() { +class TrancheDisbursalRepository @Inject constructor() : ResponseCallback() { - suspend fun fetchTrancheDisbursalWidgets(accountNumber: String): RepoResult { + suspend fun fetchTrancheDisbursalWidgets( + accountNumber: String + ): RepoResult { return apiResponseCallback(retrofitService().fetchTrancheDisbursalWidgets(accountNumber)) } @@ -27,11 +28,7 @@ constructor() : ResponseCallback() { requestInstallmentDetails: RequestInstallmentDetails ): RepoResult { return apiResponseCallback( - retrofitService().postTrancheRequestDetails( - accountNumber, - requestInstallmentDetails - ) + retrofitService().postTrancheRequestDetails(accountNumber, requestInstallmentDetails) ) } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/DocumentDeleteBottomSheet.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/DocumentDeleteBottomSheet.kt index 337002a9ae..86988b29f6 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/DocumentDeleteBottomSheet.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/DocumentDeleteBottomSheet.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.dashboard.loanapplicationdetails.tranche_disbursal import android.os.Bundle @@ -42,4 +43,4 @@ class DocumentDeleteBottomSheet : BaseBottomSheet() { override val screenName: String get() = "" -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/UploadedDocsAdapter.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/UploadedDocsAdapter.kt index 1e993f8fd7..15e84cb2c4 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/UploadedDocsAdapter.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/tranche_disbursal/UploadedDocsAdapter.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.dashboard.loanapplicationdetails.tranche_disbursal import android.annotation.SuppressLint @@ -73,12 +74,15 @@ class UploadedDocsAdapter( fun addDoc(hlSelectedData: HlSelectedFileData) { trancheDocDataList.add( TrancheDocData( - if (hlSelectedData.isLargeFile.orFalse()) UploadStatus.FILE_TOO_LARGE else UploadStatus.UPLOADING, + if (hlSelectedData.isLargeFile.orFalse()) UploadStatus.FILE_TOO_LARGE + else UploadStatus.UPLOADING, hlSelectedData ) ) showAddIcon = - (maxUploads - (trancheDocDataList.filter { it.uploadStatus != UploadStatus.FILE_TOO_LARGE }).size > 0) + (maxUploads - + (trancheDocDataList.filter { it.uploadStatus != UploadStatus.FILE_TOO_LARGE }) + .size > 0) notifyDataSetChanged() } @@ -89,7 +93,10 @@ class UploadedDocsAdapter( ) { run loop@{ trancheDocDataList.forEach { trancheDocData -> - if (trancheDocData.hlSelectedFileData?.documentReferenceId == hlsSelectedFileData?.documentReferenceId) { + if ( + trancheDocData.hlSelectedFileData?.documentReferenceId == + hlsSelectedFileData?.documentReferenceId + ) { trancheDocData.uploadStatus = uploadStatus trancheDocData.awsKey = awsKey return@loop @@ -102,10 +109,17 @@ class UploadedDocsAdapter( fun removeDoc(hlsSelectedFileData: HlSelectedFileData?) { run loop@{ trancheDocDataList.forEach { trancheDocData -> - if (trancheDocData.hlSelectedFileData?.documentReferenceId == hlsSelectedFileData?.documentReferenceId) { + if ( + trancheDocData.hlSelectedFileData?.documentReferenceId == + hlsSelectedFileData?.documentReferenceId + ) { trancheDocDataList.remove(trancheDocData) showAddIcon = - (maxUploads - (trancheDocDataList.filter { it.uploadStatus != UploadStatus.FILE_TOO_LARGE }).size > 0) + (maxUploads - + (trancheDocDataList.filter { + it.uploadStatus != UploadStatus.FILE_TOO_LARGE + }) + .size > 0) return@loop } } @@ -116,9 +130,7 @@ class UploadedDocsAdapter( inner class AddDocumentVH(val binding: ViewHlAddDocumentToUploadBinding) : RecyclerView.ViewHolder(binding.root) { fun bind() { - binding.root.setOnClickListener { - addDocumentCallback.invoke() - } + binding.root.setOnClickListener { addDocumentCallback.invoke() } } } @@ -162,7 +174,4 @@ class UploadedDocsAdapter( } } } - } - - diff --git a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/viewmodels/RequestInstallmentFragmentVM.kt b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/viewmodels/RequestInstallmentFragmentVM.kt index b8f30bb393..9674a6d1cd 100644 --- a/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/viewmodels/RequestInstallmentFragmentVM.kt +++ b/app/src/main/java/com/naviapp/dashboard/loanapplicationdetails/viewmodels/RequestInstallmentFragmentVM.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.dashboard.loanapplicationdetails.viewmodels import android.os.Bundle @@ -19,27 +20,24 @@ import com.naviapp.dashboard.loanapplicationdetails.repositories.TrancheDisbursa import com.naviapp.dashboard.loanapplicationdetails.tranche_disbursal.RequestInstallmentFragment import com.naviapp.network.ApiErrorTagType import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch -import javax.inject.Inject @ExperimentalCoroutinesApi @HiltViewModel class RequestInstallmentFragmentVM @Inject -constructor( - private val repository: TrancheDisbursalRepository -) : ViewModel() { +constructor(private val repository: TrancheDisbursalRepository) : ViewModel() { private val _requestInstallmentStateFlow = MutableStateFlow(RequestInstallmentViewState.Loading) val requestInstallmentStateFlow = _requestInstallmentStateFlow.asSharedFlow() - private val _postDetailsStateFlow = - MutableStateFlow(PostDetailsState.Init) + private val _postDetailsStateFlow = MutableStateFlow(PostDetailsState.Init) val postDetailsStateFlow = _postDetailsStateFlow.asSharedFlow() var screenName: String? = null @@ -51,10 +49,12 @@ constructor( CoroutineExceptionHandler { _, throwable -> screenName?.let { NaviTrackEvent.trackEventOnClickStream( - "{$screenName}_error", eventValues = mapOf( - propertyMessage to (throwable.message ?: ""), - propertyErrorTag to errorTag - ) + "{$screenName}_error", + eventValues = + mapOf( + propertyMessage to (throwable.message ?: ""), + propertyErrorTag to errorTag + ) ) } viewModelScope.launch { @@ -67,13 +67,20 @@ constructor( } fun fetchTrancheDisbursalWidgets(arguments: Bundle?) { - viewModelScope.launch(coroutineExceptionHandler(ApiErrorTagType.REQUEST_INSTALLMENT_DETAILS)) { + viewModelScope.launch( + coroutineExceptionHandler(ApiErrorTagType.REQUEST_INSTALLMENT_DETAILS) + ) { _requestInstallmentStateFlow.emit(RequestInstallmentViewState.Loading) - val response = repository.fetchTrancheDisbursalWidgets( - arguments?.getString(RequestInstallmentFragment.ARG_ACCOUNT_NUMBER)!! - ) - if (response.data != null && response.error == null && response.errors.isNullOrEmpty()) { - _requestInstallmentStateFlow.emit(RequestInstallmentViewState.Success(response.data!!)) + val response = + repository.fetchTrancheDisbursalWidgets( + arguments?.getString(RequestInstallmentFragment.ARG_ACCOUNT_NUMBER)!! + ) + if ( + response.data != null && response.error == null && response.errors.isNullOrEmpty() + ) { + _requestInstallmentStateFlow.emit( + RequestInstallmentViewState.Success(response.data!!) + ) } else { sendErrorEvent( ApiErrorTagType.REQUEST_INSTALLMENT_DETAILS, @@ -91,11 +98,14 @@ constructor( ) { viewModelScope.launch(coroutineExceptionHandler(ApiErrorTagType.POST_INSTALLMENT_DETAILS)) { _postDetailsStateFlow.emit(PostDetailsState.Loading) - val response = repository.postInstallmentDetails( - arguments?.getString(RequestInstallmentFragment.ARG_ACCOUNT_NUMBER)!!, - requestInstallmentDetails - ) - if (response.data != null && response.error == null && response.errors.isNullOrEmpty()) { + val response = + repository.postInstallmentDetails( + arguments?.getString(RequestInstallmentFragment.ARG_ACCOUNT_NUMBER)!!, + requestInstallmentDetails + ) + if ( + response.data != null && response.error == null && response.errors.isNullOrEmpty() + ) { _postDetailsStateFlow.emit(PostDetailsState.Success(response.data!!)) } else { sendErrorEvent( @@ -115,20 +125,23 @@ constructor( ) { screenName?.let { NaviTrackEvent.trackEventOnClickStream( - "${screenName}_error", eventValues = mapOf( - propertyMessage to if (error != null) { - error.message ?: "null" - } else { - errors?.getOrNull(0)?.message ?: "null" - }, - propertyStatusCode to (error?.statusCode?.toString() - ?: (errors?.getOrNull(0)?.code ?: "null")), - propertyErrorTag to errorTag - ) + "${screenName}_error", + eventValues = + mapOf( + propertyMessage to + if (error != null) { + error.message ?: "null" + } else { + errors?.getOrNull(0)?.message ?: "null" + }, + propertyStatusCode to + (error?.statusCode?.toString() + ?: (errors?.getOrNull(0)?.code ?: "null")), + propertyErrorTag to errorTag + ) ) } } - } sealed class RequestInstallmentViewState { @@ -142,4 +155,4 @@ sealed class PostDetailsState { object Failure : PostDetailsState() object Loading : PostDetailsState() object Init : PostDetailsState() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/menu/customersupport/activities/AboutUsActivity.kt b/app/src/main/java/com/naviapp/dashboard/menu/customersupport/activities/AboutUsActivity.kt index 58fbe34910..f0dd9280b7 100644 --- a/app/src/main/java/com/naviapp/dashboard/menu/customersupport/activities/AboutUsActivity.kt +++ b/app/src/main/java/com/naviapp/dashboard/menu/customersupport/activities/AboutUsActivity.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -44,42 +44,37 @@ class AboutUsActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContent { - RenderAboutUsScreen() - } + setContent { RenderAboutUsScreen() } } @Composable private fun RenderAboutUsScreen() { ConstraintLayout( - modifier = Modifier - .fillMaxSize() - .padding( - start = dimensionResource(id = R.dimen.dp_30), - end = dimensionResource(id = R.dimen.dp_30), - bottom = dimensionResource(id = R.dimen.dp_20) - ) + modifier = + Modifier.fillMaxSize() + .padding( + start = dimensionResource(id = R.dimen.dp_30), + end = dimensionResource(id = R.dimen.dp_30), + bottom = dimensionResource(id = R.dimen.dp_20) + ) ) { - val ( - backIv, aboutUsTv, bodyTv, logoIv, - copyrightTv - ) = createRefs() + val (backIv, aboutUsTv, bodyTv, logoIv, copyrightTv) = createRefs() Image( painter = painterResource(id = R.drawable.ic_back_arrow_svg), contentDescription = null, - modifier = Modifier - .constrainAs(backIv) { - top.linkTo(parent.top, 40.dp) - start.linkTo(parent.start) - } - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { - naviAnalyticsEventTracker.onBackButtonTap() - finish() - } - .layoutId(backIv) + modifier = + Modifier.constrainAs(backIv) { + top.linkTo(parent.top, 40.dp) + start.linkTo(parent.start) + } + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null + ) { + naviAnalyticsEventTracker.onBackButtonTap() + finish() + } + .layoutId(backIv) ) Text( text = stringResource(R.string.about_us), @@ -87,12 +82,12 @@ class AboutUsActivity : BaseActivity() { color = Black1A1A1A, fontFamily = composeFontFamily, fontWeight = getFontWeight(FontWeightEnum.BOLD), - modifier = Modifier - .constrainAs(aboutUsTv) { - top.linkTo(backIv.bottom, 30.dp) - start.linkTo(parent.start) - } - .layoutId(aboutUsTv) + modifier = + Modifier.constrainAs(aboutUsTv) { + top.linkTo(backIv.bottom, 30.dp) + start.linkTo(parent.start) + } + .layoutId(aboutUsTv) ) Text( text = stringResource(R.string.about_us_details), @@ -102,27 +97,27 @@ class AboutUsActivity : BaseActivity() { letterSpacing = 0.01.em, fontFamily = composeFontFamily, fontWeight = getFontWeight(FontWeightEnum.SEMI_BOLD), - modifier = Modifier - .constrainAs(bodyTv) { - top.linkTo(aboutUsTv.bottom, 24.dp) - start.linkTo(parent.start) - end.linkTo(parent.end) - bottom.linkTo(logoIv.top, 8.dp) - height = Dimension.fillToConstraints - } - .verticalScroll(state = rememberScrollState(), enabled = true) - .layoutId(bodyTv) + modifier = + Modifier.constrainAs(bodyTv) { + top.linkTo(aboutUsTv.bottom, 24.dp) + start.linkTo(parent.start) + end.linkTo(parent.end) + bottom.linkTo(logoIv.top, 8.dp) + height = Dimension.fillToConstraints + } + .verticalScroll(state = rememberScrollState(), enabled = true) + .layoutId(bodyTv) ) Image( painter = painterResource(id = R.drawable.ic_new_navi_logo_with_text), contentDescription = "Navi Logo", - modifier = Modifier - .constrainAs(logoIv) { - bottom.linkTo(copyrightTv.top, 8.dp) - start.linkTo(parent.start) - end.linkTo(parent.end) - } - .layoutId(logoIv) + modifier = + Modifier.constrainAs(logoIv) { + bottom.linkTo(copyrightTv.top, 8.dp) + start.linkTo(parent.start) + end.linkTo(parent.end) + } + .layoutId(logoIv) ) Text( text = stringResource(R.string.copyright_text), @@ -130,13 +125,13 @@ class AboutUsActivity : BaseActivity() { color = WhiteCCCCCC, fontFamily = composeFontFamily, fontWeight = getFontWeight(FontWeightEnum.SEMI_BOLD), - modifier = Modifier - .constrainAs(copyrightTv) { - start.linkTo(parent.start) - end.linkTo(parent.end) - bottom.linkTo(parent.bottom) - } - .layoutId(copyrightTv) + modifier = + Modifier.constrainAs(copyrightTv) { + start.linkTo(parent.start) + end.linkTo(parent.end) + bottom.linkTo(parent.bottom) + } + .layoutId(copyrightTv) ) } } @@ -156,4 +151,4 @@ class AboutUsActivity : BaseActivity() { companion object { const val TAG = "ABOUT_US_ACTIVITY" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/dashboard/menu/utils/MenuUtil.kt b/app/src/main/java/com/naviapp/dashboard/menu/utils/MenuUtil.kt index 59490c8f98..99b9c36a87 100644 --- a/app/src/main/java/com/naviapp/dashboard/menu/utils/MenuUtil.kt +++ b/app/src/main/java/com/naviapp/dashboard/menu/utils/MenuUtil.kt @@ -57,7 +57,8 @@ fun openEmailScreenWithSubjectAndBody( context: Context, customerSupportEmail: String? = CUSTOMER_CARE_EMAIL, subject: String? = null, - body: String? = null + body: String? = null, + chooserTitle: String? = null ) { try { val selectorIntent = Intent(Intent.ACTION_SENDTO) @@ -67,7 +68,7 @@ fun openEmailScreenWithSubjectAndBody( intent.putExtra(Intent.EXTRA_SUBJECT, subject) intent.putExtra(Intent.EXTRA_TEXT, body) intent.selector = selectorIntent - context.startActivity(Intent.createChooser(intent, "Send feedback")) + context.startActivity(Intent.createChooser(intent, chooserTitle ?: "Send feedback")) } catch (e: Exception) { e.log() } diff --git a/app/src/main/java/com/naviapp/errors/fragments/OfferRejectedFragment.kt b/app/src/main/java/com/naviapp/errors/fragments/OfferRejectedFragment.kt index a5a70e7817..8afe11d7dd 100644 --- a/app/src/main/java/com/naviapp/errors/fragments/OfferRejectedFragment.kt +++ b/app/src/main/java/com/naviapp/errors/fragments/OfferRejectedFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -16,15 +16,15 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent +import com.navi.base.model.CtaData +import com.navi.base.model.LineItem +import com.navi.base.sharedpref.CommonPrefConstants.USER_EXTERNAL_ID +import com.navi.base.sharedpref.PreferenceManager import com.navi.chat.models.NaviChatSystemLocalData import com.navi.chat.ui.activities.NaviChatActivity import com.navi.chat.utils.* import com.navi.common.extensions.isNotNullAndNotEmpty -import com.navi.base.model.CtaData import com.navi.common.model.GenericErrorResponse -import com.navi.base.model.LineItem -import com.navi.base.sharedpref.CommonPrefConstants.USER_EXTERNAL_ID -import com.navi.base.sharedpref.PreferenceManager import com.navi.common.ui.fragment.ActionErrorFragment import com.navi.common.ui.fragment.ActionErrorFragment.Companion.DOCUMENT_ERROR_ICON import com.navi.common.ui.fragment.ActionErrorFragment.Companion.USER_ERROR_ICON @@ -64,7 +64,9 @@ import kotlin.math.roundToInt @AndroidEntryPoint class OfferRejectedFragment : BaseFragment(), FragmentListener { private lateinit var binding: OfferRejectedFragmentBinding - private val viewModel by lazy { ViewModelProvider(this).get(OfferRejectedFragmentVM::class.java) } + private val viewModel by lazy { + ViewModelProvider(this).get(OfferRejectedFragmentVM::class.java) + } private var isHomeLoan: Boolean = false private val analyticsEventTracker = NaviAnalytics.naviAnalytics.OfferRejected() private var isSoftReject: Boolean = false @@ -88,10 +90,11 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { viewModel.sendLinkResponse.observeNonNull(viewLifecycleOwner) { response -> hideLoader() context?.let { it -> - val toastView = HomeLoanDigitalHelper.getVerificationLinkView( - getString(R.string.verification_link_sent_to, response.name), - it - ) + val toastView = + HomeLoanDigitalHelper.getVerificationLinkView( + getString(R.string.verification_link_sent_to, response.name), + it + ) it.customToast( customView = toastView, offsetY = resources.getDimension(R.dimen._100dp).toInt() @@ -107,16 +110,18 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { } private fun openHLTrackerCta() { - val cta = CtaData( - url = NaviDeepLinkNavigator.HOME_LOAN_STATUS_TRACKER, - parameters = listOf( - LineItem( - Constants.LOAN_APPLICATION_ID, - viewModel.homeLoanApplicationId - ?: queryMap[Constants.LOAN_APPLICATION_ID].toString() - ) + val cta = + CtaData( + url = NaviDeepLinkNavigator.HOME_LOAN_STATUS_TRACKER, + parameters = + listOf( + LineItem( + Constants.LOAN_APPLICATION_ID, + viewModel.homeLoanApplicationId + ?: queryMap[Constants.LOAN_APPLICATION_ID].toString() + ) + ) ) - ) NaviDeepLinkNavigator.navigate(activity, cta, finish = true) } @@ -127,17 +132,12 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { val error = arguments?.getParcelable(ErrorActivity.SECOND_LOAN_ERROR_DATA) error?.title?.let { binding.offerRejectedTitleTv.text = it } error?.description?.let { binding.offerRejectedDescriptionTv.text = it } - error?.reasonsHeading?.let { - binding.possibleReasonsTv.text = it - } ?: kotlin.run { - binding.possibleReasonsTv.visibility = View.GONE - } + error?.reasonsHeading?.let { binding.possibleReasonsTv.text = it } + ?: kotlin.run { binding.possibleReasonsTv.visibility = View.GONE } setIcon(error?.iconCode) setOptionIcon(error?.numberOfDays, error?.optionIconCode) error?.reasons?.let { binding.recyclerView.adapter = RejectionReasonAdapter(it) } - error?.imageCardData?.let { - setCreditAssignmentImageCardData(it) - } + error?.imageCardData?.let { setCreditAssignmentImageCardData(it) } } else { val error = arguments?.getParcelable(ErrorActivity.ERROR_DATA) error?.title?.let { binding.offerRejectedTitleTv.text = it } @@ -148,37 +148,36 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { arguments?.getParcelable(ErrorActivity.CREDIT_ANALYSIS_DATA)?.let { binding.creditViewContainer.visibility = View.VISIBLE binding.divider.visibility = View.GONE - binding.creditViewContainer.setProperties( - it, this, R.color.white - ) + binding.creditViewContainer.setProperties(it, this, R.color.white) } arguments?.getParcelable(ErrorActivity.CARD_LIST_DATA)?.let { binding.divider.visibility = View.GONE - it.cardList?.forEachIndexed { index, element -> - addCardView(index, element) - } + it.cardList?.forEachIndexed { index, element -> addCardView(index, element) } } arguments?.getParcelable(ErrorActivity.ADD_CO_APPLICANT)?.let { bannerInfo -> - viewModel.homeLoanApplicationId = bannerInfo.cta?.parameters?.firstOrNull { - it.key == Constants.LOAN_APPLICATION_ID - }?.value + viewModel.homeLoanApplicationId = + bannerInfo.cta + ?.parameters + ?.firstOrNull { it.key == Constants.LOAN_APPLICATION_ID } + ?.value binding.addCoApplicantView.container.visibility = View.VISIBLE - binding.addCoApplicantView.container.setBackgroundResource(R.drawable.bg_red_solid_rounded_8) + binding.addCoApplicantView.container.setBackgroundResource( + R.drawable.bg_red_solid_rounded_8 + ) binding.divider.visibility = View.GONE viewModel.inactiveCoApplicants = bannerInfo.inactiveCoApplicants setInfo(bannerInfo.info) binding.addCoApplicantView.apply { title.text = bannerInfo.title subtitle.text = bannerInfo.subtitle - bannerInfo.iconCode?.let { iconCode -> - IconUtils.updateIcon(iconCode, iconIv) - } + bannerInfo.iconCode?.let { iconCode -> IconUtils.updateIcon(iconCode, iconIv) } container.setOnClickListener { viewModel.coApplicantPageCta = bannerInfo.cta addCoApplicantClick(viewModel.homeLoanApplicationId) } } - // to handle the case when a dependent view is gone and to change the constraint to another view + // to handle the case when a dependent view is gone and to change the constraint to + // another view val params = binding.divider.layoutParams as ConstraintLayout.LayoutParams params.topToBottom = binding.addCoApplicantView.root.id params.startToStart = ConstraintSet.PARENT_ID @@ -194,22 +193,27 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { binding.chatView.setBackground(R.drawable.bg_rounded_rect_colordeepbluegray_8) binding.chatView.visibility = View.VISIBLE binding.chatView.setOnClickListener { - val naviChatSystemLocalData = NaviChatSystemLocalData( - source = if (isHomeLoan) { - ChatHLScreens.HL_SANCTION_REJECTED_SCREEN.name - } else if (isSoftReject) { - ChatPLScreens.PL_SOFT_REJECTION_SCREEN.name - } else { - ChatPLScreens.PL_HARD_REJECTION_SCREEN.name - }, - sourceId = DEFAULT_SOURCE_ID_FOR_PL, - currentUserName = PreferenceManager.getObjectPrefrences( - Constants.CURRENT_USER, - UserDetail::class.java - )?.name.orEmpty(), - externalCustomerId = PreferenceManager.getStringPreference(USER_EXTERNAL_ID) - .orEmpty() - ) + val naviChatSystemLocalData = + NaviChatSystemLocalData( + source = + if (isHomeLoan) { + ChatHLScreens.HL_SANCTION_REJECTED_SCREEN.name + } else if (isSoftReject) { + ChatPLScreens.PL_SOFT_REJECTION_SCREEN.name + } else { + ChatPLScreens.PL_HARD_REJECTION_SCREEN.name + }, + sourceId = DEFAULT_SOURCE_ID_FOR_PL, + currentUserName = + PreferenceManager.getObjectPrefrences( + Constants.CURRENT_USER, + UserDetail::class.java + ) + ?.name + .orEmpty(), + externalCustomerId = + PreferenceManager.getStringPreference(USER_EXTERNAL_ID).orEmpty() + ) NaviTrackEvent.trackEventOnClickStream( CHAT_TOUCH_POINT_CLICKED, mapOf( @@ -251,9 +255,7 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { binding.requestLoanImageBanner.setOnClickListener { imageBannerData.cta?.let { ctaData -> creditAssignmentAnalytics.creditAssignmentBannerClicked() - activity?.let { activity -> - NaviDeepLinkNavigator.navigate(activity, ctaData) - } + activity?.let { activity -> NaviDeepLinkNavigator.navigate(activity, ctaData) } } } } @@ -263,9 +265,11 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { bannerInfo.inactiveCoApplicants?.isNotEmpty()?.let { viewModel.inactiveCoApplicants = bannerInfo.inactiveCoApplicants } - bannerInfo.cta?.parameters?.firstOrNull { it.key == Constants.LOAN_APPLICATION_ID }?.value?.let { - viewModel.homeLoanApplicationId = it - } + bannerInfo.cta + ?.parameters + ?.firstOrNull { it.key == Constants.LOAN_APPLICATION_ID } + ?.value + ?.let { viewModel.homeLoanApplicationId = it } val cardView = CardWithSubCardsView(context, null) cardView.apply { @@ -281,15 +285,19 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { private fun selectCardView(bannerInfo: BannerInfo) { bannerInfo.cta?.let { - if (it.url == NaviDeepLinkNavigator.HOME_LOAN_POST_ELIGIBILITY_V2.plus(Constants.DIVIDER) - .plus(SubScreen.HL_ADD_COAPPLICANT) + if ( + it.url == + NaviDeepLinkNavigator.HOME_LOAN_POST_ELIGIBILITY_V2.plus(Constants.DIVIDER) + .plus(SubScreen.HL_ADD_COAPPLICANT) ) { viewModel.coApplicantPageCta = it addCoApplicantClick(viewModel.homeLoanApplicationId) } else { NaviDeepLinkNavigator.navigate(activity, it, true) analyticsEventTracker.onUploadBankStatement( - it.parameters?.firstOrNull { lineItem -> lineItem.key == KEY_REFERENCE_ID }?.value, + it.parameters + ?.firstOrNull { lineItem -> lineItem.key == KEY_REFERENCE_ID } + ?.value, viewModel.homeLoanApplicationId ) } @@ -319,14 +327,14 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { binding.infoTv.text = it.title it.iconCode?.let { iconCode -> binding.infoIv.setImageResource(IconUtils.getIconResourceId(iconCode)) - } ?: run { - binding.infoIv.visibility = View.GONE } + ?: run { binding.infoIv.visibility = View.GONE } } - } ?: run { - binding.infoTv.visibility = View.GONE - binding.infoIv.visibility = View.GONE } + ?: run { + binding.infoTv.visibility = View.GONE + binding.infoIv.visibility = View.GONE + } } private fun setIcon(iconType: String?) { @@ -366,22 +374,14 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { queryMap[Constants.LOAN_ACTION_TYPE] ) if (viewModel.inactiveCoApplicants.isNullOrEmpty()) { - viewModel.coApplicantPageCta?.let { - navigateToCoApplicantPage(it) - } + viewModel.coApplicantPageCta?.let { navigateToCoApplicantPage(it) } } else { viewModel.inactiveCoApplicants?.let { inactiveCoApplicants -> val coApplicantList = ArrayList() coApplicantList.addAll(inactiveCoApplicants) - coApplicantList.forEach { - it.selected = false - } + coApplicantList.forEach { it.selected = false } coApplicantList[0].selected = true - coApplicantList.add( - HomeLoanCoApplicantResponse( - addCoAppOption = true - ) - ) + coApplicantList.add(HomeLoanCoApplicantResponse(addCoAppOption = true)) openAddExistingCoApplicants(coApplicantList, loanApplicationId) } } @@ -392,24 +392,23 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { loanApplicationId: String? ) { val addCoApplicantsBottomSheet = - AddCoApplicantsBottomSheet.getInstance(Bundle().apply { - putParcelableArrayList( - AddCoApplicantsBottomSheet.CO_APPLICANT_LIST, - coApplicantList - ) - }) + AddCoApplicantsBottomSheet.getInstance( + Bundle().apply { + putParcelableArrayList( + AddCoApplicantsBottomSheet.CO_APPLICANT_LIST, + coApplicantList + ) + } + ) safelyShowBottomSheet( addCoApplicantsBottomSheet, AddCoApplicantsBottomSheet.ADD_COAPPLICANTS_BOTTOM_SHEET ) - addCoApplicantsBottomSheet.selectedCoApplicant.observeNonNull( - viewLifecycleOwner - ) { homeLoanCoApplicantResponse -> + addCoApplicantsBottomSheet.selectedCoApplicant.observeNonNull(viewLifecycleOwner) { + homeLoanCoApplicantResponse -> if (homeLoanCoApplicantResponse.addCoAppOption == true) { - viewModel.coApplicantPageCta?.let { - navigateToCoApplicantPage(it) - } + viewModel.coApplicantPageCta?.let { navigateToCoApplicantPage(it) } } else { postAddExistingCoApplicant(homeLoanCoApplicantResponse, loanApplicationId) } @@ -425,7 +424,8 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { val tempQueryMap = HashMap() viewModel.postCoApplicantActivation( CoApplicantActivationRequest(it), - homeLoanCoApplicantResponse.status, tempQueryMap.apply { + homeLoanCoApplicantResponse.status, + tempQueryMap.apply { put(Constants.ACTION, ACTIVATE_CO_APPLICANT) put( Constants.LOAN_APPLICATION_ID, @@ -445,12 +445,7 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { } NaviDeepLinkNavigator.navigate( activity, - CtaData( - url = cta.url, - parameters = tempQueryMap.map { - LineItem(it.key, it.value) - } - ), + CtaData(url = cta.url, parameters = tempQueryMap.map { LineItem(it.key, it.value) }), true ) } @@ -460,9 +455,7 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener { companion object { const val TAG = "OFFER_REJECTED_FRAGMENT" - fun newInstance(arguments: Bundle?) = OfferRejectedFragment().apply { - this.arguments = arguments - } + fun newInstance(arguments: Bundle?) = + OfferRejectedFragment().apply { this.arguments = arguments } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/errors/fragments/ProfileRejectedFragment.kt b/app/src/main/java/com/naviapp/errors/fragments/ProfileRejectedFragment.kt index 71c9ab9e24..b1c745edbe 100644 --- a/app/src/main/java/com/naviapp/errors/fragments/ProfileRejectedFragment.kt +++ b/app/src/main/java/com/naviapp/errors/fragments/ProfileRejectedFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,15 +13,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.navi.analytics.utils.NaviTrackEvent +import com.navi.base.model.CtaData +import com.navi.base.sharedpref.CommonPrefConstants.USER_EXTERNAL_ID +import com.navi.base.sharedpref.PreferenceManager import com.navi.chat.models.NaviChatSystemLocalData import com.navi.chat.ui.activities.NaviChatActivity import com.navi.chat.utils.* import com.navi.common.extensions.isNotNullAndNotEmpty import com.navi.common.extensions.orFalse -import com.navi.base.model.CtaData import com.navi.common.model.GenericErrorResponse -import com.navi.base.sharedpref.CommonPrefConstants.USER_EXTERNAL_ID -import com.navi.base.sharedpref.PreferenceManager import com.navi.common.ui.fragment.ActionErrorFragment import com.navi.common.ui.fragment.ActionErrorFragment.Companion.DOCUMENT_ERROR_ICON import com.navi.common.ui.fragment.ActionErrorFragment.Companion.MFI_PROFILE_ERROR_ICON @@ -46,8 +46,8 @@ import com.naviapp.models.UserDetail import com.naviapp.models.response.ChatNudge import com.naviapp.models.response.CreditAnalysisData import com.naviapp.models.response.ErrorContent -import com.naviapp.utils.Constants import com.naviapp.personalloan.getloan.creditAssignment.models.ImageBannerData +import com.naviapp.utils.Constants import com.naviapp.utils.getScreenWidth import com.naviapp.utils.loadUrlIntoImageView import kotlin.math.roundToInt @@ -77,17 +77,12 @@ class ProfileRejectedFragment : BaseFragment(), FragmentListener { val error = arguments?.getParcelable(SECOND_LOAN_ERROR_DATA) error?.title?.let { binding.offerRejectedTitleTv.text = it } error?.description?.let { binding.offerRejectedDescriptionTv.text = it } - error?.reasonsHeading?.let { - binding.eligibilityCriteriaTv.text = it - } ?: kotlin.run { - binding.eligibilityCriteriaTv.visibility = View.GONE - } + error?.reasonsHeading?.let { binding.eligibilityCriteriaTv.text = it } + ?: kotlin.run { binding.eligibilityCriteriaTv.visibility = View.GONE } setIcon(error?.iconCode) setOptionIcon(error?.numberOfDays, error?.optionIconCode) error?.reasons?.let { binding.recyclerView.adapter = RejectionReasonAdapter(it) } - error?.imageCardData?.let { - setCreditAssignmentImageCardData(it) - } + error?.imageCardData?.let { setCreditAssignmentImageCardData(it) } } else { val error = arguments?.getParcelable(ERROR_DATA) error?.title?.let { binding.offerRejectedTitleTv.text = it } @@ -98,9 +93,7 @@ class ProfileRejectedFragment : BaseFragment(), FragmentListener { arguments?.getParcelable(CREDIT_ANALYSIS_DATA)?.let { binding.creditViewContainer.visibility = View.VISIBLE binding.divider.visibility = View.GONE - binding.creditViewContainer.setProperties( - it, this, R.color.white - ) + binding.creditViewContainer.setProperties(it, this, R.color.white) } val chatNudge = arguments?.getParcelable(CHAT_NUDGE_DATA) chatNudge?.let { @@ -115,20 +108,25 @@ class ProfileRejectedFragment : BaseFragment(), FragmentListener { if (isHomeLoan) { // TODO enable in-house chat for HL } else { - val naviChatSystemLocalData = NaviChatSystemLocalData( - source = if (isSoftReject) { - ChatPLScreens.PL_SOFT_REJECTION_SCREEN.name - } else { - ChatPLScreens.PL_HARD_REJECTION_SCREEN.name - }, - sourceId = DEFAULT_SOURCE_ID_FOR_PL, - currentUserName = PreferenceManager.getObjectPrefrences( - Constants.CURRENT_USER, - UserDetail::class.java - )?.name.orEmpty(), - externalCustomerId = PreferenceManager.getStringPreference(USER_EXTERNAL_ID) - .orEmpty() - ) + val naviChatSystemLocalData = + NaviChatSystemLocalData( + source = + if (isSoftReject) { + ChatPLScreens.PL_SOFT_REJECTION_SCREEN.name + } else { + ChatPLScreens.PL_HARD_REJECTION_SCREEN.name + }, + sourceId = DEFAULT_SOURCE_ID_FOR_PL, + currentUserName = + PreferenceManager.getObjectPrefrences( + Constants.CURRENT_USER, + UserDetail::class.java + ) + ?.name + .orEmpty(), + externalCustomerId = + PreferenceManager.getStringPreference(USER_EXTERNAL_ID).orEmpty() + ) NaviTrackEvent.trackEventOnClickStream( CHAT_TOUCH_POINT_CLICKED, mapOf( @@ -214,4 +212,4 @@ class ProfileRejectedFragment : BaseFragment(), FragmentListener { override fun onItemClick(ctaData: CtaData) { NaviDeepLinkNavigator.navigate(activity, ctaData) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/activity/StoryActivity.kt b/app/src/main/java/com/naviapp/home/activity/StoryActivity.kt index da2caf421f..af4601cf0c 100644 --- a/app/src/main/java/com/naviapp/home/activity/StoryActivity.kt +++ b/app/src/main/java/com/naviapp/home/activity/StoryActivity.kt @@ -29,6 +29,7 @@ import com.navi.common.ui.activity.BaseActivity import com.navi.common.utils.observeNonNull import com.navi.common.utils.orTrue import com.navi.common.utils.orZero +import com.navi.common.utils.toCtaData import com.navi.insurance.util.FALSE import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics @@ -36,12 +37,10 @@ import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.common.navigator.NaviDeepLinkNavigator.HOME import com.naviapp.databinding.StoryLayoutBinding import com.naviapp.models.AppStories -import com.navi.common.utils.toCtaData import com.naviapp.models.StoryHeader import com.naviapp.storyview.StoriesProgressView import com.naviapp.storyview.StoryVM import com.naviapp.utils.Constants.CARD_GROUP_REFERENCE_ID - import com.naviapp.utils.getDensityName import com.naviapp.utils.isNetworkAvailable import com.naviapp.utils.loadUrlIntoImageView diff --git a/app/src/main/java/com/naviapp/home/analytics/LandingScreenAnalytics.kt b/app/src/main/java/com/naviapp/home/analytics/LandingScreenAnalytics.kt index 9e70364269..e3f01ca21f 100644 --- a/app/src/main/java/com/naviapp/home/analytics/LandingScreenAnalytics.kt +++ b/app/src/main/java/com/naviapp/home/analytics/LandingScreenAnalytics.kt @@ -20,9 +20,9 @@ object LandingScreenAnalytics { parameters: MutableMap? ) { eventName?.let { - NaviTrackEvent.trackEventOnClickStream(it, parameters) + NaviTrackEvent.trackEvent(it, parameters) } ?: run { - NaviTrackEvent.trackEventOnClickStream(DEFAULT_EVENT_NAME, parameters) + NaviTrackEvent.trackEvent(DEFAULT_EVENT_NAME, parameters) } } } \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/home/dashboard/adapter/GridOptionsAdapter.kt b/app/src/main/java/com/naviapp/home/dashboard/adapter/GridOptionsAdapter.kt index 338717b859..f4e68f7672 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/adapter/GridOptionsAdapter.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/adapter/GridOptionsAdapter.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.home.dashboard.adapter import android.view.LayoutInflater @@ -7,9 +14,8 @@ import com.navi.base.model.ActionData import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.naviapp.databinding.GridOptionItemBinding import com.naviapp.home.dashboard.models.response.GridOption -import com.naviapp.utils.loadUrlIntoImageView -class GridOptionsAdapter(val items: List ,val onClick : (action : ActionData) -> Unit) : +class GridOptionsAdapter(val items: List, val onClick: (action: ActionData) -> Unit) : RecyclerView.Adapter() { inner class GridOptionsViewHolder(val binding: GridOptionItemBinding) : @@ -25,13 +31,12 @@ class GridOptionsAdapter(val items: List ,val onClick : (action : Ac holder.binding.title.text = items[position].text holder.binding.image.showWhenDataIsAvailable(items[position].imageUrl) holder.itemView.setOnClickListener { - items[position].actionData?.let { - onClick.invoke(it) - } + items[position].actionData?.let { onClick.invoke(it) } + } } override fun getItemCount(): Int { return items.size } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/models/response/GridOption.kt b/app/src/main/java/com/naviapp/home/dashboard/models/response/GridOption.kt index 6a7fced0d5..d46d58f537 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/models/response/GridOption.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/models/response/GridOption.kt @@ -1,13 +1,18 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.home.dashboard.models.response import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData data class GridOption( - @SerializedName("text") - val text: String? = null, - @SerializedName("imageUrl") - val imageUrl: String? = null, - @SerializedName("actionData") - val actionData: ActionData? = null -) \ No newline at end of file + @SerializedName("text") val text: String? = null, + @SerializedName("imageUrl") val imageUrl: String? = null, + @SerializedName("actionData") val actionData: ActionData? = null +) + diff --git a/app/src/main/java/com/naviapp/home/dashboard/models/response/ValidityInfoData.kt b/app/src/main/java/com/naviapp/home/dashboard/models/response/ValidityInfoData.kt new file mode 100644 index 0000000000..46bdfbafba --- /dev/null +++ b/app/src/main/java/com/naviapp/home/dashboard/models/response/ValidityInfoData.kt @@ -0,0 +1,13 @@ +package com.naviapp.home.dashboard.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.response.TextFieldData + +data class ValidityInfoData( + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("description") + val description: TextFieldData? = null, + @SerializedName("button") + val button: TextFieldData? = null +) diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/ClosedLoansFragment.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/ClosedLoansFragment.kt index ab4b5243c9..4138946599 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/ui/ClosedLoansFragment.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/ClosedLoansFragment.kt @@ -38,15 +38,12 @@ class ClosedLoansFragment : BaseFragment() { } override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_closed_loans, - container, - false - ) + binding = + DataBindingUtil.inflate(inflater, R.layout.fragment_closed_loans, container, false) return binding.root } @@ -55,9 +52,7 @@ class ClosedLoansFragment : BaseFragment() { initUI() initError( viewModel = closedLoanVM, - dialogDismissClicked = { - loadScreen() - }, + dialogDismissClicked = { loadScreen() }, showFullScreenError = true ) initObserver() @@ -65,9 +60,7 @@ class ClosedLoansFragment : BaseFragment() { } private fun initUI() { - binding.ivBack.setOnClickListener { - activity?.onBackPressed() - } + binding.ivBack.setOnClickListener { activity?.onBackPressed() } } private fun loadScreen() { @@ -81,38 +74,36 @@ class ClosedLoansFragment : BaseFragment() { setUpViewPagerAdapter(closedLoansTabList) } - closedLoanVM.errorResponse.observe(viewLifecycleOwner) { - hideShimmer() - } + closedLoanVM.errorResponse.observe(viewLifecycleOwner) { hideShimmer() } } - private fun setUpViewPagerAdapter(tabItems: List) { binding.apply { vpClosedLoans.isUserInputEnabled = false - val dashboardViewPagerAdapter = ClosedLoanViewPagerAdapter( - fragmentManger = childFragmentManager, - listOfTabs = tabItems, - lifecycle = lifecycle - ) + val dashboardViewPagerAdapter = + ClosedLoanViewPagerAdapter( + fragmentManger = childFragmentManager, + listOfTabs = tabItems, + lifecycle = lifecycle + ) vpClosedLoans.adapter = dashboardViewPagerAdapter - tlClosedLoans.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { - override fun onTabSelected(tab: TabLayout.Tab?) { - setSelectedCustomTabView(tab = tab) + tlClosedLoans.addOnTabSelectedListener( + object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab?) { + setSelectedCustomTabView(tab = tab) + } + + override fun onTabUnselected(tab: TabLayout.Tab?) { + setUnSelectedCustomTabView(tab = tab) + } + + override fun onTabReselected(tab: TabLayout.Tab?) {} } - - override fun onTabUnselected(tab: TabLayout.Tab?) { - setUnSelectedCustomTabView(tab = tab) - } - - override fun onTabReselected(tab: TabLayout.Tab?) { - - } - - }) + ) TabLayoutMediator(tlClosedLoans, vpClosedLoans) { tab, position -> - setCustomTabView(tab, tabItems[position], position) - }.attach() + setCustomTabView(tab, tabItems[position], position) + } + .attach() } setTabStartMargin(marginStart = resources.getDimension(R.dimen.layout_dp_12).toInt()) } @@ -123,8 +114,10 @@ class ClosedLoansFragment : BaseFragment() { currentPosition: Int, defaultSelectedTab: Int = 0, ) { - tab.setCustomView(R.layout.dashboard_tab_item_layout).customView - ?.findViewById(R.id.tvTabName)?.text = tabItem.tabName + tab.setCustomView(R.layout.dashboard_tab_item_layout) + .customView + ?.findViewById(R.id.tvTabName) + ?.text = tabItem.tabName if (currentPosition == defaultSelectedTab) { setSelectedCustomTabView(tab = tab) @@ -135,14 +128,13 @@ class ClosedLoansFragment : BaseFragment() { private fun setSelectedCustomTabView(tab: TabLayout.Tab?) { tab?.let { - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) ?.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.title_text_red_color - ) + ContextCompat.getColor(requireContext(), R.color.title_text_red_color) ) - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) ?.setFontStyle(FontWeightEnum.EXTRA_BOLD) it.customView?.findViewById(R.id.indicator)?.visibility = View.VISIBLE } @@ -150,14 +142,11 @@ class ClosedLoansFragment : BaseFragment() { private fun setUnSelectedCustomTabView(tab: TabLayout.Tab?) { tab?.let { - it.customView?.findViewById(R.id.tvTabName) - ?.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.santas_gray - ) - ) - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) + ?.setTextColor(ContextCompat.getColor(requireContext(), R.color.santas_gray)) + it.customView + ?.findViewById(R.id.tvTabName) ?.setFontStyle(FontWeightEnum.SEMI_BOLD) it.customView?.findViewById(R.id.indicator)?.visibility = View.GONE } @@ -186,4 +175,4 @@ class ClosedLoansFragment : BaseFragment() { companion object { const val TAG = "ClosedLoansFragment" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/DashboardFragment.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/DashboardFragment.kt index 634cf441bd..baf786d1f9 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/ui/DashboardFragment.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/DashboardFragment.kt @@ -50,15 +50,11 @@ class DashboardFragment : BaseFragment() { private var redirectTabName: String? = null override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle?, ): View { - binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_dashboard, - container, - false - ) + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_dashboard, container, false) return binding.root } @@ -68,9 +64,7 @@ class DashboardFragment : BaseFragment() { initUI() initErrorInFragment( viewModel = dashboardVM, - fullScreenErrorDismissed = { - loadScreen() - }, + fullScreenErrorDismissed = { loadScreen() }, showFullScreenError = true, containerViewId = R.id.flError ) @@ -90,9 +84,7 @@ class DashboardFragment : BaseFragment() { dashboardVM.dashboardTabs.observeNonNull(viewLifecycleOwner) { dashboardTabsResponse -> binding.flError.isVisible = false hideShimmer() - dashboardTabsResponse.tabs?.let { tabs -> - setUpViewPagerAdapter(tabs) - } + dashboardTabsResponse.tabs?.let { tabs -> setUpViewPagerAdapter(tabs) } } dashboardVM.errorResponse.observe(viewLifecycleOwner) { @@ -109,29 +101,30 @@ class DashboardFragment : BaseFragment() { private fun setUpViewPagerAdapter(tabItems: List) { binding.apply { vpDashboard.isUserInputEnabled = false - val dashboardViewPagerAdapter = DashboardViewPagerAdapter( - fragmentManger = childFragmentManager, - listOfTabs = tabItems, - lifecycle = lifecycle - ) + val dashboardViewPagerAdapter = + DashboardViewPagerAdapter( + fragmentManger = childFragmentManager, + listOfTabs = tabItems, + lifecycle = lifecycle + ) vpDashboard.adapter = dashboardViewPagerAdapter - tlDashboard.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { - override fun onTabSelected(tab: TabLayout.Tab?) { - setSelectedCustomTabView(tab = tab) + tlDashboard.addOnTabSelectedListener( + object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab?) { + setSelectedCustomTabView(tab = tab) + } + + override fun onTabUnselected(tab: TabLayout.Tab?) { + setUnSelectedCustomTabView(tab = tab) + } + + override fun onTabReselected(tab: TabLayout.Tab?) {} } - - override fun onTabUnselected(tab: TabLayout.Tab?) { - setUnSelectedCustomTabView(tab = tab) - } - - override fun onTabReselected(tab: TabLayout.Tab?) { - - } - - }) + ) TabLayoutMediator(tlDashboard, vpDashboard) { tab, position -> - setCustomTabView(tab, tabItems[position], position) - }.attach() + setCustomTabView(tab, tabItems[position], position) + } + .attach() redirectTabName?.let { tabName -> vpDashboard.currentItem = dashboardVM.getRedirectTabIndex(tabName) } @@ -145,8 +138,10 @@ class DashboardFragment : BaseFragment() { currentPosition: Int, defaultSelectedTab: Int = 0, ) { - tab.setCustomView(R.layout.dashboard_tab_item_layout).customView - ?.findViewById(R.id.tvTabName)?.text = tabItem.name + tab.setCustomView(R.layout.dashboard_tab_item_layout) + .customView + ?.findViewById(R.id.tvTabName) + ?.text = tabItem.name if (currentPosition == defaultSelectedTab) { setSelectedCustomTabView(tab = tab) @@ -157,14 +152,13 @@ class DashboardFragment : BaseFragment() { private fun setSelectedCustomTabView(tab: TabLayout.Tab?) { tab?.let { - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) ?.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.title_text_red_color - ) + ContextCompat.getColor(requireContext(), R.color.title_text_red_color) ) - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) ?.setFontStyle(FontWeightEnum.EXTRA_BOLD) it.customView?.findViewById(R.id.indicator)?.visibility = VISIBLE } @@ -172,14 +166,11 @@ class DashboardFragment : BaseFragment() { private fun setUnSelectedCustomTabView(tab: TabLayout.Tab?) { tab?.let { - it.customView?.findViewById(R.id.tvTabName) - ?.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.santas_gray - ) - ) - it.customView?.findViewById(R.id.tvTabName) + it.customView + ?.findViewById(R.id.tvTabName) + ?.setTextColor(ContextCompat.getColor(requireContext(), R.color.santas_gray)) + it.customView + ?.findViewById(R.id.tvTabName) ?.setFontStyle(FontWeightEnum.SEMI_BOLD) it.customView?.findViewById(R.id.indicator)?.visibility = GONE } @@ -225,9 +216,7 @@ class DashboardFragment : BaseFragment() { } } try { - val action = actions?.firstOrNull { - it.second == response.second - }?.first + val action = actions?.firstOrNull { it.second == response.second }?.first val errorFragment = ActionErrorFragment.getInstance( response.first, @@ -246,18 +235,23 @@ class DashboardFragment : BaseFragment() { return@observeNonNull } } - if (activity == null - || !isAdded - || !isResumed - || childFragmentManager.isDestroyed - || childFragmentManager.isStateSaved + if ( + activity == null || + !isAdded || + !isResumed || + childFragmentManager.isDestroyed || + childFragmentManager.isStateSaved ) { return@observeNonNull } try { val ft = childFragmentManager.beginTransaction() val prev = childFragmentManager.findFragmentByTag(NaviChatErrorFragment.TAG) - if (prev != null && !childFragmentManager.isStateSaved && !childFragmentManager.isDestroyed) { + if ( + prev != null && + !childFragmentManager.isStateSaved && + !childFragmentManager.isDestroyed + ) { ft.remove(prev).commit() } val errorFragment = @@ -281,11 +275,8 @@ class DashboardFragment : BaseFragment() { companion object { const val TAG = "DASHBOARD" - fun getInstance(bundle: Bundle?) = DashboardFragment().apply { - arguments = bundle - } + fun getInstance(bundle: Bundle?) = DashboardFragment().apply { arguments = bundle } } override val screenName: String = NaviAnalytics.NEW_DASHBOARD - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/GridOptionsBottomSheet.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/GridOptionsBottomSheet.kt index 5e7803a3aa..4e73d72d0a 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/ui/GridOptionsBottomSheet.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/GridOptionsBottomSheet.kt @@ -1,8 +1,16 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.home.dashboard.ui import android.os.Bundle import android.view.ViewStub import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.GridLayoutManager import com.google.common.reflect.TypeToken @@ -17,46 +25,44 @@ import com.naviapp.home.dashboard.models.response.GridOption class GridOptionsBottomSheet : BaseBottomSheet() { private lateinit var binding: GridOptionBottomsheetLayoutBinding - private lateinit var onOptionClick : (action : ActionData) -> Unit + private lateinit var onOptionClick: (action: ActionData) -> Unit override fun setContainerView(viewStub: ViewStub) { - setBackgroundTint( - ContextCompat.getColor( - requireContext(), - R.color.grey_alabaster - ) - ) + setBackgroundTint(ContextCompat.getColor(requireContext(), R.color.grey_alabaster)) viewStub.layoutResource = R.layout.grid_option_bottomsheet_layout binding = DataBindingUtil.getBinding(viewStub.inflate())!! + setPadding(0, 0, 0, 0) val listType = object : TypeToken>() {}.type - val dataList: List = - Gson().fromJson(arguments?.getString(data), listType) + val dataList: List = Gson().fromJson(arguments?.getString(data), listType) - binding.options.apply { - adapter = GridOptionsAdapter( - dataList, onOptionClick - ) - layoutManager = GridLayoutManager(context, 3) + val error = arguments?.getString(error) + + binding.headerContainer.isVisible = error?.let { + binding.headerTitle.text = it + true + } ?: run { + false } + binding.options.apply { + adapter = GridOptionsAdapter(dataList, onOptionClick) + layoutManager = GridLayoutManager(context, 3) + } } - fun setClickListener(onOptionClick : (action : ActionData) -> Unit){ + fun setClickListener(onOptionClick: (action: ActionData) -> Unit) { this.onOptionClick = onOptionClick } - override val screenName: String get() = NaviAnalytics.POLICY_GRID_BOTTOMSHEET companion object { const val TAG = "GridOptionsBottomSheet" - const val data = "data" + const val data = "data" + const val error = "error" fun getInstance(bundle: Bundle): GridOptionsBottomSheet { - return GridOptionsBottomSheet().apply { - arguments = bundle - } + return GridOptionsBottomSheet().apply { arguments = bundle } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/ProductFragment.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/ProductFragment.kt index 44196e5126..7a875aae4a 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/ui/ProductFragment.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/ProductFragment.kt @@ -20,8 +20,8 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import com.google.gson.Gson -import com.navi.analytics.utils.NaviTrackEvent import com.navi.amc.utils.openPlayStore +import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.* import com.navi.base.sharedpref.CommonPrefConstants.USER_EXTERNAL_ID import com.navi.base.sharedpref.PreferenceManager @@ -72,11 +72,12 @@ import com.naviapp.utils.Constants.OPD import com.naviapp.utils.Constants.POLICY_BENEFIT_TYPE import com.naviapp.utils.Constants.POLICY_ID import com.naviapp.utils.Constants.SHOW_BOTTOMSHEET +import com.naviapp.utils.Constants.VALIDITY_INFO_BOTTOM_SHEET import dagger.hilt.android.AndroidEntryPoint import timber.log.Timber @AndroidEntryPoint -class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBottomSheetListener { +class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBottomSheetListener, ValidityInfoBottomSheet.Callback { private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() private lateinit var binding: FragmentProductBinding @@ -123,6 +124,7 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo private fun readArguments() { dashboardTab = arguments?.getParcelable(KEY_DASHBOARD_TAB_DATA) + dashboardTab?.name?.let { NaviTrackEvent.trackEvent("init_" + it + "_dashboard_tab") } } private fun initUI() { @@ -131,7 +133,8 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo } private fun initObserver() { - productVM.dashboardContentResponse.observeNonNull(viewLifecycleOwner) { dashboardContentResponse -> + productVM.dashboardContentResponse.observeNonNull(viewLifecycleOwner) { + dashboardContentResponse -> binding.flError.isVisible = false binding.rvProducts.isVisible = true getFilteredNaviWidgets(dashboardContentResponse.listOfWidgets)?.let { listOfWidgets -> @@ -164,10 +167,8 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo binding.rvProducts.isVisible = false hideShimmer() } - } - private fun handlePolices(value: String?) { val jsonData = Gson().fromJson(value, DashboardPolicyBenefitData::class.java) jsonData?.listOfPolicyBenefits?.let { @@ -194,10 +195,12 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo keyValue.value?.let { benefitType = it } } } - startActivity(Intent(activity, BenefitWebViewActivity::class.java).apply { - putExtra(BenefitWebViewActivity.INTENT_POLICY_ID, policyBenefitData?.policyId) - putExtra(BenefitWebViewActivity.INTENT_BENEFIT_TYPE, benefitType) - }) + startActivity( + Intent(activity, BenefitWebViewActivity::class.java).apply { + putExtra(BenefitWebViewActivity.INTENT_POLICY_ID, policyBenefitData?.policyId) + putExtra(BenefitWebViewActivity.INTENT_BENEFIT_TYPE, benefitType) + } + ) } } @@ -273,7 +276,7 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo NaviDeepLinkNavigator.navigate( activity = activity, ctaData = - CtaData(url = naviClickAction.url, parameters = naviClickAction.parameters) + CtaData(url = naviClickAction.url, parameters = naviClickAction.parameters) ) } is NavigateClickAction -> { @@ -313,10 +316,7 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo startActivity(Intent(context, ClosedLoansActivity::class.java)) } is ActionData -> { - NaviDeepLinkNavigator.navigate( - activity, - naviClickAction.toCtaData() - ) + NaviDeepLinkNavigator.navigate(activity, naviClickAction.toCtaData()) } is CtaData -> { NaviAnalytics.naviAnalytics.sendAnalyticsEvent( @@ -348,34 +348,38 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo } private fun redirectToPhone(parameters: List?) { - val intent = Intent( - Intent.ACTION_DIAL, - Uri.parse("tel:" + (parameters?.filter { it.key == Constants.PHONE } - ?.getOrNull(0)?.value ?: (FirebaseRemoteConfigHelper.getString( - FirebaseRemoteConfigHelper.HELP_LINE_NUMBER - )))) - ) + val intent = + Intent( + Intent.ACTION_DIAL, + Uri.parse( + "tel:" + + (parameters?.filter { it.key == Constants.PHONE }?.getOrNull(0)?.value + ?: (FirebaseRemoteConfigHelper.getString( + FirebaseRemoteConfigHelper.HELP_LINE_NUMBER + ))) + ) + ) startActivity(intent) } - private fun toShowBottomSheet(action: ActionData?) { val splitDeepLink = action?.url?.split("/") val secondIdentifier = splitDeepLink?.getOrNull(1) when (secondIdentifier) { GRID_OPTION_BOTTOMSHEET -> { - val bundle = - Bundle().apply { - putString( - GridOptionsBottomSheet.data, - action.parameters?.getOrNull(0)?.value - ) + val bundle = Bundle().apply { + action.parameters?.forEach { + putString(it.key, it.value) } + } val bottomsheet = GridOptionsBottomSheet.getInstance(bundle) bottomsheet.setClickListener { it.let { bottomsheet.safelyDismissDialog() onClick(it) + it.metaData?.clickedData?.let { analyticsData -> + sendAnalytics(analyticsData) + } } } safelyShowBottomSheet(bottomsheet, GridOptionsBottomSheet.TAG) @@ -389,6 +393,12 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo BOTTOMSHEET_SELECT_POLICY -> { handlePolices(action.parameters?.getOrNull(0)?.value) } + VALIDITY_INFO_BOTTOM_SHEET -> { + val bottomSheet = ValidityInfoBottomSheet().apply { + arguments = Bundle().apply { action.parameters?.forEach { putString(it.key, it.value) } } + } + safelyShowBottomSheet(bottomSheet, ValidityInfoBottomSheet.TAG) + } } } @@ -511,4 +521,10 @@ class ProductFragment : BaseFragment(), WidgetCallback, DashboardPolicyBenefitBo } } } -} \ No newline at end of file + + override fun onCtaClick(ctaData: CtaData) { + NaviAnalytics.naviAnalytics.sendAnalyticsEvent(ctaData.analyticsEventProperties) + NaviDeepLinkNavigator.navigate(activity, ctaData) + } + +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/TrancheDisbursalStatusBottomSheet.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/TrancheDisbursalStatusBottomSheet.kt index a0110e2e3d..2c0d965f1d 100644 --- a/app/src/main/java/com/naviapp/home/dashboard/ui/TrancheDisbursalStatusBottomSheet.kt +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/TrancheDisbursalStatusBottomSheet.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.home.dashboard.ui import android.os.Bundle @@ -40,9 +41,12 @@ class TrancheDisbursalStatusBottomSheet : BaseBottomSheet() { val widgetData = arguments?.getParcelable(ARG_WIDGET_DATA) - widgetData?.actionData?.metaData?.viewedData?.takeIf { it.eventName.isNotNull() }?.let { - NaviTrackEvent.trackEvent(it.eventName ?: EMPTY, it.parameters) - } + widgetData + ?.actionData + ?.metaData + ?.viewedData + ?.takeIf { it.eventName.isNotNull() } + ?.let { NaviTrackEvent.trackEvent(it.eventName ?: EMPTY, it.parameters) } binding.headerTitle.setSpannableString(widgetData?.header?.title) binding.headerSubTitle.setSpannableString(widgetData?.header?.subTitle) @@ -51,23 +55,26 @@ class TrancheDisbursalStatusBottomSheet : BaseBottomSheet() { widgetData?.actionData?.toCtaData()?.let { cta -> binding.action.text = cta.title binding.action.setOnClickListener { - widgetData.actionData?.metaData?.clickedData?.takeIf { it.eventName.isNotNull() } - ?.let { - NaviTrackEvent.trackEvent(it.eventName ?: EMPTY, it.parameters) - } + widgetData.actionData + ?.metaData + ?.clickedData + ?.takeIf { it.eventName.isNotNull() } + ?.let { NaviTrackEvent.trackEvent(it.eventName ?: EMPTY, it.parameters) } NaviDeepLinkNavigator.navigate(activity, cta) safelyDismissDialog() } - } ?: run { - binding.action.isVisible = false - } - widgetData?.header?.leftIcon?.takeIf { it.iconCode?.isNotEmpty().orFalse() }?.let { - Glide.with(view.context) - .load(NaviWidgetIconUtils.getImageFromIconCode(it.iconCode)) - .into(binding.headerLeftIcon) - } ?: run { - binding.headerLeftIcon.isVisible = false } + ?: run { binding.action.isVisible = false } + widgetData + ?.header + ?.leftIcon + ?.takeIf { it.iconCode?.isNotEmpty().orFalse() } + ?.let { + Glide.with(view.context) + .load(NaviWidgetIconUtils.getImageFromIconCode(it.iconCode)) + .into(binding.headerLeftIcon) + } + ?: run { binding.headerLeftIcon.isVisible = false } } override val screenName: String @@ -77,5 +84,4 @@ class TrancheDisbursalStatusBottomSheet : BaseBottomSheet() { const val TAG = "NaviWidgetBottomSheet" const val ARG_WIDGET_DATA = "widgetData" } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/dashboard/ui/ValidityInfoBottomSheet.kt b/app/src/main/java/com/naviapp/home/dashboard/ui/ValidityInfoBottomSheet.kt new file mode 100644 index 0000000000..79a6c177f0 --- /dev/null +++ b/app/src/main/java/com/naviapp/home/dashboard/ui/ValidityInfoBottomSheet.kt @@ -0,0 +1,70 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ +package com.naviapp.home.dashboard.ui + +import android.os.Bundle +import android.view.View +import android.view.ViewStub +import androidx.databinding.DataBindingUtil +import androidx.lifecycle.lifecycleScope +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.navi.base.model.CtaData +import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler +import com.navi.naviwidgets.extensions.setTextFieldData +import com.naviapp.R +import com.naviapp.databinding.ValidityInfoBottomSheetBinding +import com.naviapp.home.dashboard.models.response.ValidityInfoData + +class ValidityInfoBottomSheet : BaseBottomSheet() { + + private lateinit var binding: ValidityInfoBottomSheetBinding + + override fun setContainerView(viewStub: ViewStub) { + viewStub.layoutResource = R.layout.validity_info_bottom_sheet + binding = DataBindingUtil.getBinding(viewStub.inflate())!! + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val dataString = arguments?.getString(ARG_DATA) + + val type = object : TypeToken() {}.type + val data = Gson().fromJson(dataString, type) + + if (data != null) { + binding.title.setTextFieldData(data.title) + binding.subTitle.setTextFieldData(data.description) + binding.button.setTextFieldData(data.button) + data.button?.cta?.let { cta -> + binding.button.addOnMultipleClicksHandler { + (parentFragment as? Callback)?.onCtaClick(cta) + safelyDismissDialog() + } + } + } else { + lifecycleScope.launchWhenResumed { + safelyDismissDialog() + } + } + } + + override val screenName: String + get() = TAG + + companion object { + const val TAG = "ValidityInfoBottomSheet" + const val ARG_DATA = "data" + } + + interface Callback { + fun onCtaClick(ctaData: CtaData) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/home/fragment/ProfileFragment.kt b/app/src/main/java/com/naviapp/home/fragment/ProfileFragment.kt index 54175d2be8..721f11b9a1 100644 --- a/app/src/main/java/com/naviapp/home/fragment/ProfileFragment.kt +++ b/app/src/main/java/com/naviapp/home/fragment/ProfileFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -23,6 +23,7 @@ import com.navi.base.sharedpref.PreferenceManager import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.orTrue import com.navi.common.utils.setStatusBarColor +import com.navi.common.utils.toCtaData import com.navi.naviwidgets.adapters.NaviAdapter import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.models.NaviWidget @@ -32,7 +33,6 @@ import com.navi.naviwidgets.utils.APP_UPDATE_ENABLE import com.navi.naviwidgets.viewholder.ViewHolderFactoryImpl import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.utils.toCtaData import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.common.navigator.NaviDeepLinkNavigator.CHAT import com.naviapp.common.navigator.NaviDeepLinkNavigator.FAQ @@ -49,13 +49,8 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class ProfileFragment : BaseFragment(), WidgetCallback { private lateinit var binding: FragmentProfileLnBinding - private val naviAdapter = NaviAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) - private val viewModel by lazy { - ViewModelProvider(this).get(ProfileVM::class.java) - } + private val naviAdapter = NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) + private val viewModel by lazy { ViewModelProvider(this).get(ProfileVM::class.java) } private var sharedVM: DashboardSharedVM? = null private val naviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() @@ -63,21 +58,22 @@ class ProfileFragment : BaseFragment(), WidgetCallback { get() = NaviAnalytics.NEW_PROFILE override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_profile_ln, - container, - false - ) + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_profile_ln, container, false) initUI() - initError(viewModel, dialogDismissClicked = { - reInitData() - }, showFullScreenError = true, container = R.id.container) + initError( + viewModel, + dialogDismissClicked = { reInitData() }, + showFullScreenError = true, + container = R.id.container + ) initObservers() - viewModel.fetchProfileItems(PreferenceManager.getBooleanPreference(APP_UPDATE_ENABLE,false)) + viewModel.fetchProfileItems( + PreferenceManager.getBooleanPreference(APP_UPDATE_ENABLE, false) + ) return binding.root } @@ -94,7 +90,9 @@ class ProfileFragment : BaseFragment(), WidgetCallback { binding.shimmerLayout.visibility = View.VISIBLE binding.recycleView.visibility = View.GONE binding.shimmerLayout.startShimmer() - viewModel.fetchProfileItems(PreferenceManager.getBooleanPreference(APP_UPDATE_ENABLE,false)) + viewModel.fetchProfileItems( + PreferenceManager.getBooleanPreference(APP_UPDATE_ENABLE, false) + ) } private fun initObservers() { @@ -106,11 +104,8 @@ class ProfileFragment : BaseFragment(), WidgetCallback { response?.contentWidget?.let { contentWidget -> updateStatusBar(contentWidget.firstOrNull()) binding.recycleView.apply { - layoutManager = LinearLayoutManager( - context, - LinearLayoutManager.VERTICAL, - false - ) + layoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) naviAdapter.list = contentWidget adapter = naviAdapter } @@ -124,9 +119,7 @@ class ProfileFragment : BaseFragment(), WidgetCallback { private fun updateStatusBar(widget: NaviWidget?) { if (widget is UserDetailsWidget) { - widget.userDetailsWidgetData?.gradient?.let { - setStatusBarColor(it) - } + widget.userDetailsWidgetData?.gradient?.let { setStatusBarColor(it) } } } @@ -179,20 +172,12 @@ class ProfileFragment : BaseFragment(), WidgetCallback { override fun widgetStateChanged(position: Int?, data: Pair?, action: String) { if (!isAdded || activity?.isFinishing.orTrue()) return - position?.let { - naviAdapter.notifyItemChanged( - it, - WidgetChangedData(action, data?.second) - ) - } + position?.let { naviAdapter.notifyItemChanged(it, WidgetChangedData(action, data?.second)) } } override fun widgetError(position: Int, payload: Any?, action: String) { if (!isAdded || activity?.isFinishing.orTrue()) return - naviAdapter.notifyItemChanged( - position, - WidgetChangedData(action, payload) - ) + naviAdapter.notifyItemChanged(position, WidgetChangedData(action, payload)) } override fun widgetScrollTo(position: Int) { @@ -206,11 +191,9 @@ class ProfileFragment : BaseFragment(), WidgetCallback { } companion object { - const val TAG = "PROFILE" + const val TAG = "PROFILE" fun newInstance(bundle: Bundle?): ProfileFragment { - return ProfileFragment().apply { - arguments = bundle - } + return ProfileFragment().apply { arguments = bundle } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/home/fragment/SelectableItemsBottomSheet.kt b/app/src/main/java/com/naviapp/home/fragment/SelectableItemsBottomSheet.kt index 3aaec13433..83c029eeba 100644 --- a/app/src/main/java/com/naviapp/home/fragment/SelectableItemsBottomSheet.kt +++ b/app/src/main/java/com/naviapp/home/fragment/SelectableItemsBottomSheet.kt @@ -12,11 +12,11 @@ import android.view.ViewStub import androidx.databinding.DataBindingUtil import com.navi.base.model.ActionData import com.navi.base.model.CtaData +import com.navi.common.listeners.ClickableTextListener import com.navi.common.ui.fragment.BaseBottomSheet import com.navi.naviwidgets.models.response.AdditionalBottomSheetData import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics.Companion.SELECTABLE_OPTION_BOTTOMSHEET -import com.navi.common.listeners.ClickableTextListener import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.SingleSelectionOptionBottomsheetBinding import com.naviapp.utils.Constants.SELECTABLE_OPTION_CLICK diff --git a/app/src/main/java/com/naviapp/home/fragment/UniversalBottomSheet.kt b/app/src/main/java/com/naviapp/home/fragment/UniversalBottomSheet.kt index e15301b6a0..233e533563 100644 --- a/app/src/main/java/com/naviapp/home/fragment/UniversalBottomSheet.kt +++ b/app/src/main/java/com/naviapp/home/fragment/UniversalBottomSheet.kt @@ -12,11 +12,11 @@ import android.view.View import android.view.ViewStub import androidx.databinding.DataBindingUtil import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.common.utils.toCtaData import com.navi.naviwidgets.extensions.setTextFieldData import com.navi.naviwidgets.models.response.GenericBottomSheetData import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics.Companion.UNIVERSAL_BOTTOMSHEET -import com.navi.common.utils.toCtaData import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.UniversalBottomsheetBinding import com.naviapp.utils.IconUtils diff --git a/app/src/main/java/com/naviapp/home/respository/ProfileRepository.kt b/app/src/main/java/com/naviapp/home/respository/ProfileRepository.kt index 5f99ccab90..efc721e9de 100644 --- a/app/src/main/java/com/naviapp/home/respository/ProfileRepository.kt +++ b/app/src/main/java/com/naviapp/home/respository/ProfileRepository.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -12,9 +12,11 @@ import com.naviapp.network.retrofit.ResponseCallback import com.naviapp.network.retrofit.RetrofitService import javax.inject.Inject -class ProfileRepository @Inject constructor(@SuperAppRetroFit private val superAppRetrofitService: RetrofitService) : +class ProfileRepository +@Inject +constructor(@SuperAppRetroFit private val superAppRetrofitService: RetrofitService) : ResponseCallback() { suspend fun fetchProfileItems(appUpdate: Boolean) = apiResponseCallback(superAppRetrofitService.fetchProfileItems(appUpdate)) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/adapter/HLPermissionAdapter.kt b/app/src/main/java/com/naviapp/homeloandigital/common/adapter/HLPermissionAdapter.kt index 1d69e09b11..0c633ac883 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/adapter/HLPermissionAdapter.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/adapter/HLPermissionAdapter.kt @@ -18,7 +18,7 @@ import android.content.pm.PackageManager import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.navi.common.utils.setShakeAnimation +import com.navi.insurance.util.setShakeAnimation import com.naviapp.databinding.HlPermissionTileLayoutBinding import com.naviapp.homeloandigital.models.response.HLPermissionTile import com.naviapp.utils.IconUtils diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/customview/OptionSelectBottomsheet.kt b/app/src/main/java/com/naviapp/homeloandigital/common/customview/OptionSelectBottomsheet.kt index 8d8d3a4136..ece9554d19 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/customview/OptionSelectBottomsheet.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/customview/OptionSelectBottomsheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.homeloandigital.common.customview import android.os.Bundle @@ -6,9 +13,9 @@ import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.LinearLayoutManager import com.navi.base.model.ActionData import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.common.utils.toCtaData import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.utils.toCtaData import com.naviapp.databinding.OptionSelectBottomsheetLayoutBinding import com.naviapp.homeloandigital.common.adapter.OptionSelectAdapter import com.naviapp.homeloandigital.common.adapter.OptionSelectorListener @@ -23,9 +30,7 @@ class OptionSelectBottomsheet : BaseBottomSheet(), OptionSelectorListener { override fun setContainerView(viewStub: ViewStub) { viewStub.layoutResource = R.layout.option_select_bottomsheet_layout binding = DataBindingUtil.getBinding(viewStub.inflate())!! - arguments?.getParcelableArrayList(CTA_DATA_LIST)?.let { - initRecyclerView(it) - } + arguments?.getParcelableArrayList(CTA_DATA_LIST)?.let { initRecyclerView(it) } binding.title.text = arguments?.getString(TITLE) setActionButton() } @@ -69,4 +74,4 @@ class OptionSelectBottomsheet : BaseBottomSheet(), OptionSelectorListener { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/BaseHomeLoanActivity.kt b/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/BaseHomeLoanActivity.kt index ba13bb3521..1f74a8c87e 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/BaseHomeLoanActivity.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/BaseHomeLoanActivity.kt @@ -45,6 +45,7 @@ import com.naviapp.homeloandigital.eligibility.fragment.cityinput.HomeLoanSearch import com.naviapp.homeloandigital.eligibility.fragment.form.HomeLoanFormFragment import com.naviapp.homeloandigital.ipa.fragment.HomeLoanEmiTenureFragment import com.naviapp.homeloandigital.ipa.fragment.HomeLoanIPAFragment +import com.naviapp.homeloandigital.landingpage.fragment.HomeLoanLandingPageFragment import com.naviapp.homeloandigital.loandetails.fragment.HomeLoanDetailsV2Fragment import com.naviapp.homeloandigital.models.HelpBottomSheetData import com.naviapp.homeloandigital.posteligibility.fragment.* @@ -89,7 +90,7 @@ abstract class BaseHomeLoanActivity : BaseActivity(), Navigator { super.onCreate(savedInstanceState) setupQueryMap(intent.extras) val subScreen = intent.getStringExtra(REDIRECT_STATUS) - if (!BaseUtils.isUserLoggedIn()) { + if (!BaseUtils.isUserLoggedIn() && subScreen != SubScreen.HL_LANDING_PAGE.screenName) { ScreenNavigator.instance.startActivity( this, ScreenNavigator.REGISTRATION_SCREEN, @@ -235,6 +236,7 @@ abstract class BaseHomeLoanActivity : BaseActivity(), Navigator { HomeLoanAutoDebitChangeBankFragment.newInstance(arguments) SubScreen.HL_KYC_APPLICANTS -> HomeLoanApplicantsFragment.newInstance(arguments) SubScreen.HL_IMPROVE_OFFER -> HomeLoanApplicantsFragment.newInstance(arguments) + SubScreen.HL_LANDING_PAGE -> HomeLoanLandingPageFragment.newInstance(arguments) else -> null } } diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/SubScreen.kt b/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/SubScreen.kt index 588559bdee..2822a3d124 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/SubScreen.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/ui/activity/SubScreen.kt @@ -41,6 +41,7 @@ enum class SubScreen(val screenName: String) { HL_AUTO_DEBIT_CHANGE_BANK("HL_AUTO_DEBIT_CHANGE_BANK"), HL_KYC_APPLICANTS("HL_KYC_APPLICANTS"), HL_IMPROVE_OFFER("HL_IMPROVE_OFFER"), + HL_LANDING_PAGE("HL_LANDING_PAGE"), UNKNOWN("UNKNOWN"); companion object { diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/ui/customview/TopNavigationHeader.kt b/app/src/main/java/com/naviapp/homeloandigital/common/ui/customview/TopNavigationHeader.kt index b33d12c258..215abdb00b 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/ui/customview/TopNavigationHeader.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/ui/customview/TopNavigationHeader.kt @@ -6,6 +6,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.ColorUtils @@ -100,6 +101,10 @@ class TopNavigationHeader @JvmOverloads constructor( interface TopNavigationHeaderInterface { fun setHeaderBackgroundColor(@ColorRes color: Int){} + fun setBackIcon(@DrawableRes resId: Int) {} + fun setHeaderTextColor(@ColorRes colorId: Int) {} + fun setDividerVisibility(visibilityState: Int) {} + fun setBackIconPadding(left: Int, top: Int, right: Int, bottom: Int) {} fun setHelpAndCallIconVisibility( helpVisibility: Boolean, callIconVisibility: Boolean, diff --git a/app/src/main/java/com/naviapp/homeloandigital/common/ui/fragment/BaseHomeLoanFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/common/ui/fragment/BaseHomeLoanFragment.kt index cdad23573f..8c96ff1011 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/common/ui/fragment/BaseHomeLoanFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/common/ui/fragment/BaseHomeLoanFragment.kt @@ -2,8 +2,8 @@ package com.naviapp.homeloandigital.common.ui.fragment import android.os.Bundle import com.navi.common.ui.fragment.BaseFragment -import com.naviapp.common.transformer.HLLatencyMapper import com.naviapp.common.navigator.ScreenNavigator +import com.naviapp.common.transformer.HLLatencyMapper import com.naviapp.homeloandigital.common.ui.activity.BaseHomeLoanActivity import com.naviapp.utils.Constants.KEY_LOAN_APPLICATION_ID import com.naviapp.utils.Constants.LOAN_ACTION_TYPE @@ -51,8 +51,12 @@ abstract class BaseHomeLoanFragment : BaseFragment() { setDataToLatencyMapper() } - internal fun setDataToLatencyMapper() { - hlLatencyMapper.setData(queryMap[KEY_LOAN_APPLICATION_ID], queryMap[LOAN_ACTION_TYPE]) + internal fun setDataToLatencyMapper(eventName: String? = null) { + hlLatencyMapper.setData( + queryMap[KEY_LOAN_APPLICATION_ID], + queryMap[LOAN_ACTION_TYPE], + eventName + ) } override fun onDestroy() { diff --git a/app/src/main/java/com/naviapp/homeloandigital/eligibility/activity/HomeLoanEligibilityV2Activity.kt b/app/src/main/java/com/naviapp/homeloandigital/eligibility/activity/HomeLoanEligibilityV2Activity.kt index 732ca492a0..97aab38a96 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/eligibility/activity/HomeLoanEligibilityV2Activity.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/eligibility/activity/HomeLoanEligibilityV2Activity.kt @@ -1,12 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.homeloandigital.eligibility.activity import android.os.Bundle +import androidx.core.content.ContextCompat import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent +import com.navi.common.model.ModuleNameV2 +import com.navi.common.ui.fragment.BaseFragment import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.ui.fragment.BaseFragment +import com.naviapp.common.listeners.BackListener import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.HomeLoanEligibilityV2Binding import com.naviapp.homeloandigital.common.ui.activity.BaseHomeLoanActivity @@ -16,11 +26,14 @@ import com.naviapp.homeloandigital.common.viewmodel.PermissionVM import com.naviapp.homeloandigital.eligibility.fragment.HomeLoanPermissionFragment import com.naviapp.homeloandigital.eligibility.fragment.HomeLoanSelectTypeFragment import com.naviapp.homeloandigital.eligibility.fragment.cityinput.HomeLoanSearchInputFormFragment +import com.naviapp.homeloandigital.landingpage.fragment.HomeLoanLandingPageFragment import com.naviapp.homeloandigital.models.HelpBottomSheetData import com.naviapp.homeloandigital.posteligibility.fragment.SelfieVerificationFragment -import com.navi.common.model.ModuleNameV2 import com.naviapp.utils.Constants +import com.naviapp.utils.dpToPx +import com.naviapp.utils.setVisibilityState import dagger.hilt.android.AndroidEntryPoint +import kotlinx.android.synthetic.main.layout_top_navigation_header.view.* @AndroidEntryPoint class HomeLoanEligibilityV2Activity : BaseHomeLoanActivity(), FragmentContainer, @@ -53,15 +66,20 @@ class HomeLoanEligibilityV2Activity : BaseHomeLoanActivity(), FragmentContainer, } override fun onBackPressed() { - val currentFragment = supportFragmentManager.findFragmentById(containerId) - if (currentFragment is HomeLoanSelectTypeFragment) { - hlCommonAnalyticsTracker.onBackPress( - getCurrentFragmentScreenName(), - queryMap[Constants.LOAN_ACTION_TYPE] - ) - launchHome() - } else { - super.onBackPressed() + when (val currentFragment = supportFragmentManager.findFragmentById(containerId)) { + is HomeLoanSelectTypeFragment -> { + hlCommonAnalyticsTracker.onBackPress( + getCurrentFragmentScreenName(), + queryMap[Constants.LOAN_ACTION_TYPE] + ) + launchHome() + } + is HomeLoanLandingPageFragment -> { + (currentFragment as BackListener).onBackPressed() + } + else -> { + super.onBackPressed() + } } } @@ -97,7 +115,28 @@ class HomeLoanEligibilityV2Activity : BaseHomeLoanActivity(), FragmentContainer, get() = ModuleNameV2.HL override val screenNameForNavigation: String = NaviDeepLinkNavigator.HOME_LOAN_ELIGIBILITY_V2 override fun setHeaderBackgroundColor(color: Int) { + binding.header.backgroundColor = ContextCompat.getColor(this, color) + } + override fun setBackIcon(resId: Int) { + binding.header.icon.setImageResource(resId) + } + + override fun setHeaderTextColor(colorId: Int) { + binding.header.help_tv.setTextColor( + ContextCompat.getColor( + binding.header.help_tv.context, + colorId + ) + ) + } + + override fun setDividerVisibility(visibilityState: Int) { + binding.header.divider.setVisibilityState(visibilityState) + } + + override fun setBackIconPadding(left: Int, top: Int, right: Int, bottom: Int) { + binding.header.icon.setPadding(dpToPx(left), dpToPx(top), dpToPx(right), dpToPx(bottom)) } override fun setHelpAndCallIconVisibility( diff --git a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/HomeLoanSelectTypeFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/HomeLoanSelectTypeFragment.kt index c8385ba8c3..7d217fffd4 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/HomeLoanSelectTypeFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/HomeLoanSelectTypeFragment.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.homeloandigital.eligibility.fragment import android.content.Context @@ -86,22 +93,30 @@ class HomeLoanSelectTypeFragment : BaseHomeLoanFragment(), HLAdapterClickInterfa viewModel.homeLoanSelectResponse.observeNonNull(this) { hideLoader() queryMap[LOAN_ACTION_TYPE] = - it.second.parameters?.first { predicate -> predicate.key == LOAN_ACTION_TYPE }?.value.toString() + it.second.parameters + ?.first { predicate -> predicate.key == LOAN_ACTION_TYPE } + ?.value + .toString() queryMap[Constants.LOAN_APPLICATION_ID] = it.first?.loanApplicationId.toString() setDataToLatencyMapper() val navigator = activity - val ctaData = it.second.copy( - parameters = listOf( - LineItem( - key = LOAN_ACTION_TYPE, - value = it.second.parameters?.first { predicate -> predicate.key == LOAN_ACTION_TYPE }?.value - ), - LineItem( - key = Constants.LOAN_APPLICATION_ID, - value = it.first?.loanApplicationId - ) + val ctaData = + it.second.copy( + parameters = + listOf( + LineItem( + key = LOAN_ACTION_TYPE, + value = + it.second.parameters + ?.first { predicate -> predicate.key == LOAN_ACTION_TYPE } + ?.value + ), + LineItem( + key = Constants.LOAN_APPLICATION_ID, + value = it.first?.loanApplicationId + ) + ) ) - ) if (navigator is Navigator) { navigator.navigateTo(ctaData) } @@ -109,60 +124,49 @@ class HomeLoanSelectTypeFragment : BaseHomeLoanFragment(), HLAdapterClickInterfa } private fun initRecyclerView(items: List?) { - items?.let { - adapter = HomeLoanTypeAdapter(it, this) - } + items?.let { adapter = HomeLoanTypeAdapter(it, this) } val mLayoutManager = GridLayoutManager(context, 2) - mLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { - override fun getSpanSize(position: Int): Int { - return when (adapter.getItemViewType(position)) { - HomeLoanTypeAdapter.HL_FIRST_CARD -> 2 - else -> 1 + mLayoutManager.spanSizeLookup = + object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + return when (adapter.getItemViewType(position)) { + HomeLoanTypeAdapter.HL_FIRST_CARD -> 2 + else -> 1 + } } } - } binding.HlTypesList.layoutManager = mLayoutManager binding.HlTypesList.adapter = adapter - binding.HlTypesList.addItemDecoration(object : RecyclerView.ItemDecoration() { - val px = resources.getDimensionPixelSize(R.dimen.dp_6) - override fun getItemOffsets( - outRect: Rect, - view: View, - parent: RecyclerView, - state: RecyclerView.State - ) { - outRect.set( - px, - px, - px, - px - ) + binding.HlTypesList.addItemDecoration( + object : RecyclerView.ItemDecoration() { + val px = resources.getDimensionPixelSize(R.dimen.dp_6) + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + outRect.set(px, px, px, px) + } } - }) + ) } private fun checkForAppUpdate() { updateApp(screenName = Constants.HOME_LOAN_NEW) { updateAppDetails, startUpdatingApp -> - updateInAppDialog = UpdateInAppDialog(updateAppDetails, requireContext()) { - startUpdatingApp.invoke() - } + updateInAppDialog = + UpdateInAppDialog(updateAppDetails, requireContext()) { startUpdatingApp.invoke() } updateInAppDialog.safelyShowDialog() } } private fun updateApp( screenName: String, - showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? = null + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? = null ) { activity?.let { if (it is BaseHomeLoanActivity) { - it.updateApp( - screenName = screenName, - showDialog = showDialog - ) + it.updateApp(screenName = screenName, showDialog = showDialog) } } } @@ -178,13 +182,15 @@ class HomeLoanSelectTypeFragment : BaseHomeLoanFragment(), HLAdapterClickInterfa ) analyticsTracker.onBannerClicked(loanTypeValue) } else { - val resultCta = listCta.map{ - it.toActionData() - } - val bundle = Bundle().apply { - putParcelableArrayList(OptionSelectBottomsheet.CTA_DATA_LIST, ArrayList(resultCta)) - putString(OptionSelectBottomsheet.TITLE, title) - } + val resultCta = listCta.map { it.toActionData() } + val bundle = + Bundle().apply { + putParcelableArrayList( + OptionSelectBottomsheet.CTA_DATA_LIST, + ArrayList(resultCta) + ) + putString(OptionSelectBottomsheet.TITLE, title) + } val optionSelectBottomSheet = OptionSelectBottomsheet.newInstance(bundle, this) safelyShowBottomSheet(optionSelectBottomSheet, OptionSelectBottomsheet.TAG) } @@ -193,16 +199,13 @@ class HomeLoanSelectTypeFragment : BaseHomeLoanFragment(), HLAdapterClickInterfa override fun onBackPressed() { viewModel.homeLoanSelectTypeScreenDetails.value?.header?.backCta?.let { NaviDeepLinkNavigator.navigate(activity, it, clearTask = true) - } ?: run { - launchHome() } + ?: run { launchHome() } } companion object { fun newInstance(bundle: Bundle? = null): HomeLoanSelectTypeFragment { - return HomeLoanSelectTypeFragment().apply { - arguments = bundle - } + return HomeLoanSelectTypeFragment().apply { arguments = bundle } } } @@ -223,6 +226,4 @@ class HomeLoanSelectTypeFragment : BaseHomeLoanFragment(), HLAdapterClickInterfa override val hlScreenName: String get() = NaviAnalytics.HOME_LOAN_SELECT_TYPE_SCREEN - } - diff --git a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/FormBaseFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/FormBaseFragment.kt index 2dfee898a9..f26f1201e0 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/FormBaseFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/FormBaseFragment.kt @@ -1,14 +1,23 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.homeloandigital.eligibility.fragment.form import android.os.Bundle import android.text.TextUtils import android.view.View import androidx.lifecycle.ViewModelProvider -import com.navi.common.firebasedb.* import com.navi.base.model.CtaData import com.navi.base.model.LineItem +import com.navi.common.firebasedb.* import com.navi.common.model.RequestConfig import com.navi.common.utils.ApiPollScheduler +import com.navi.common.utils.observeNonNull +import com.navi.common.utils.orTrue import com.naviapp.analytics.utils.LoadTimeEventTracker import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.fragment.CommonBottomSheet @@ -18,13 +27,13 @@ import com.naviapp.homeloandigital.common.ui.fragment.BaseHomeLoanFragment import com.naviapp.homeloandigital.eligibility.fragment.panerror.PanErrorFragmentV2 import com.naviapp.homeloandigital.models.FormResponse import com.naviapp.network.ApiErrorTagType -import com.navi.common.utils.observeNonNull -import com.navi.common.utils.orTrue import com.naviapp.utils.orValue abstract class FormBaseFragment : BaseHomeLoanFragment() { - internal val viewModel by lazy { ViewModelProvider(this).get(HomeLoanFormFragmentViewModel::class.java) } + internal val viewModel by lazy { + ViewModelProvider(this).get(HomeLoanFormFragmentViewModel::class.java) + } internal var apiPollScheduler: ApiPollScheduler? = null internal var firebaseDataReceiveListener: FirebaseDataReceiveListener? = null internal var firebaseDataHelper: FirebaseDataHelper? = null @@ -76,9 +85,7 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { } } - viewModel.uiStatusData.observe(viewLifecycleOwner) { - hideLoader() - } + viewModel.uiStatusData.observe(viewLifecycleOwner) { hideLoader() } viewModel.panNameMismatchError.observe(viewLifecycleOwner) { hideLoader() @@ -91,25 +98,27 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { viewModel.bottomSheetResponse.observe(viewLifecycleOwner) { hideLoader() - val commonBottomSheet = CommonBottomSheet.newInstance( - iconCode = it.assetDetails?.icon, - title = it.title, - description = it.message, - ctaData = CtaData( - title = it.actions?.firstOrNull()?.title, - parameters = it.actions?.firstOrNull()?.parameters, - url = it.actions?.firstOrNull()?.url - ), - screenName = NaviAnalytics.HOME_LOAN_FORM_PAGE_BOTTOM_SHEET - ) - safelyShowBottomSheet( - commonBottomSheet, CommonBottomSheet.TAG - ) + val commonBottomSheet = + CommonBottomSheet.newInstance( + iconCode = it.assetDetails?.icon, + title = it.title, + description = it.message, + ctaData = + CtaData( + title = it.actions?.firstOrNull()?.title, + parameters = it.actions?.firstOrNull()?.parameters, + url = it.actions?.firstOrNull()?.url + ), + screenName = NaviAnalytics.HOME_LOAN_FORM_PAGE_BOTTOM_SHEET + ) + safelyShowBottomSheet(commonBottomSheet, CommonBottomSheet.TAG) } } private fun updateFormPageType(formResponse: FormResponse) { - formResponse.content?.widgetList?.filter { it.widgetId == FormPageType.PAN_PAGE.value } + formResponse.content + ?.widgetList + ?.filter { it.widgetId == FormPageType.PAN_PAGE.value } ?.let { if (it.isNotEmpty()) { viewModel.updateFormPageType(FormPageType.PAN_PAGE) @@ -120,21 +129,23 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { abstract fun processFormResponseData(formResponse: FormResponse) internal fun firebaseInit(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { handleAsyncResponse(it.status) } + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { handleAsyncResponse(it.status) } + } } - } firebaseDataHelper?.clear() - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - PAN_DETAILS, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + PAN_DETAILS, + requestId, + notificationPath + ) + } } internal val onPollingEnd = { @@ -143,16 +154,24 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { } internal fun apiPollInit(requestId: String, requestConfig: RequestConfig?) { - apiPollScheduler = ApiPollScheduler( - initialDelay = requestConfig?.initialDelay?.toLong() - .orValue(ApiPollScheduler.INITIAL_DELAY_FOR_API_POLL_SECONDS), - pollInterval = requestConfig?.interval.orValue(ApiPollScheduler.API_POLL_REPEAT_PERIOD_SECONDS.toInt()) - .toLong(), - numberOfRetry = requestConfig?.numOfRetries ?: ApiPollScheduler.API_POLL_RETRY_COUNT, - doOnTimeout = onPollingEnd - ) { - viewModel.fetchAsyncRequestData(requestId) - } + apiPollScheduler = + ApiPollScheduler( + initialDelay = + requestConfig + ?.initialDelay + ?.toLong() + .orValue(ApiPollScheduler.INITIAL_DELAY_FOR_API_POLL_SECONDS), + pollInterval = + requestConfig + ?.interval + .orValue(ApiPollScheduler.API_POLL_REPEAT_PERIOD_SECONDS.toInt()) + .toLong(), + numberOfRetry = requestConfig?.numOfRetries + ?: ApiPollScheduler.API_POLL_RETRY_COUNT, + doOnTimeout = onPollingEnd + ) { + viewModel.fetchAsyncRequestData(requestId) + } apiPollScheduler?.scheduleApiPoll() } @@ -191,11 +210,11 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { firebaseDataHelper, apiPollScheduler, { - val nextCta = CtaData( - url = NaviDeepLinkNavigator.HOME_LOAN_STATUS_TRACKER, - parameters = queryMap.map { - LineItem(it.key, it.value) - }) + val nextCta = + CtaData( + url = NaviDeepLinkNavigator.HOME_LOAN_STATUS_TRACKER, + parameters = queryMap.map { LineItem(it.key, it.value) } + ) moveToNextScreen(nextCta) }, errorTag @@ -207,4 +226,4 @@ abstract class FormBaseFragment : BaseHomeLoanFragment() { enum class FormPageType(val value: String) { PAN_PAGE("panNumber") } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/adapter/WidgetViewMapping.kt b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/adapter/WidgetViewMapping.kt index c2fbaac4a6..6940b37ea2 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/adapter/WidgetViewMapping.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/eligibility/fragment/form/adapter/WidgetViewMapping.kt @@ -53,21 +53,27 @@ object WidgetViewMapping { APPLICANT_ITEM_WIDGET } - val viewType = hashMapOf, Int>( - LabeledTextInputWidgetModelV2::class.java to WidgetType.LABELED_TEXT_INPUT_WIDGET.ordinal, - TextDisplayWidgetModel::class.java to WidgetType.TEXT_DISPLAY_WIDGET.ordinal, - LabeledDateInputWidgetModel::class.java to WidgetType.LABELED_DATE_INPUT_WIDGET.ordinal, - LabeledTextInputFixedHintWidgetModel::class.java to WidgetType.LABELED_TEXT_INPUT_FIXED_HINT_WIDGET.ordinal, - LabeledOptionSelectorTileWidgetModel::class.java to WidgetType.LABELED_OPTION_SELECTOR_TILE_WIDGET.ordinal, - LabeledOptionSelectorListWidgetModel::class.java to WidgetType.LABELED_OPTION_SELECTOR_LIST_WIDGET.ordinal, - LabeledTextInputSearchWidgetModel::class.java to WidgetType.LABEL_WITH_INPUT_SEARCH_WIDGET.ordinal, - TextSearchWidgetModel::class.java to WidgetType.TEXT_WITH_SEARCH_WIDGET.ordinal, - ToastWidget::class.java to WidgetType.TOAST_WIDGET.ordinal, - InfoListWidgetModel::class.java to WidgetType.INFO_LIST_WIDGET.ordinal, - ImproveOfferWidgetModel::class.java to WidgetType.IMPROVE_OFFER_WIDGET.ordinal, - ApplicantESignWidgetModel::class.java to WidgetType.APPLICANT_E_SIGN_WIDGET.ordinal, - ApplicantItemWidgetModel::class.java to WidgetType.APPLICANT_ITEM_WIDGET.ordinal - ) + val viewType = + hashMapOf, Int>( + LabeledTextInputWidgetModelV2::class.java to + WidgetType.LABELED_TEXT_INPUT_WIDGET.ordinal, + TextDisplayWidgetModel::class.java to WidgetType.TEXT_DISPLAY_WIDGET.ordinal, + LabeledDateInputWidgetModel::class.java to WidgetType.LABELED_DATE_INPUT_WIDGET.ordinal, + LabeledTextInputFixedHintWidgetModel::class.java to + WidgetType.LABELED_TEXT_INPUT_FIXED_HINT_WIDGET.ordinal, + LabeledOptionSelectorTileWidgetModel::class.java to + WidgetType.LABELED_OPTION_SELECTOR_TILE_WIDGET.ordinal, + LabeledOptionSelectorListWidgetModel::class.java to + WidgetType.LABELED_OPTION_SELECTOR_LIST_WIDGET.ordinal, + LabeledTextInputSearchWidgetModel::class.java to + WidgetType.LABEL_WITH_INPUT_SEARCH_WIDGET.ordinal, + TextSearchWidgetModel::class.java to WidgetType.TEXT_WITH_SEARCH_WIDGET.ordinal, + ToastWidget::class.java to WidgetType.TOAST_WIDGET.ordinal, + InfoListWidgetModel::class.java to WidgetType.INFO_LIST_WIDGET.ordinal, + ImproveOfferWidgetModel::class.java to WidgetType.IMPROVE_OFFER_WIDGET.ordinal, + ApplicantESignWidgetModel::class.java to WidgetType.APPLICANT_E_SIGN_WIDGET.ordinal, + ApplicantItemWidgetModel::class.java to WidgetType.APPLICANT_ITEM_WIDGET.ordinal + ) fun createViewHolder( viewType: Int, @@ -148,12 +154,13 @@ object WidgetViewMapping { LabeledTextSearchInputWidgetVH(binding.labeledInputTextSearch) as BaseViewHolder } WidgetType.TEXT_WITH_SEARCH_WIDGET.ordinal -> { - val binding: LayoutTextWithSearchBinding = DataBindingUtil.inflate( - LayoutInflater.from(parent.context), - com.navi.naviwidgets.R.layout.layout_text_with_search, - parent, - false - ) + val binding: LayoutTextWithSearchBinding = + DataBindingUtil.inflate( + LayoutInflater.from(parent.context), + com.navi.naviwidgets.R.layout.layout_text_with_search, + parent, + false + ) TextWithSearchWidgetVH(binding.textSearch) as BaseViewHolder } WidgetType.TOAST_WIDGET.ordinal -> { diff --git a/app/src/main/java/com/naviapp/homeloandigital/ipa/fragment/HomeLoanEmiTenureFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/ipa/fragment/HomeLoanEmiTenureFragment.kt index 573cf1a322..7af1ddfde9 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/ipa/fragment/HomeLoanEmiTenureFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/ipa/fragment/HomeLoanEmiTenureFragment.kt @@ -21,6 +21,7 @@ import com.navi.common.utils.isNotNull import com.navi.common.utils.observeNonNull import com.navi.common.utils.orFalse import com.navi.common.utils.orZero +import com.navi.common.utils.setCornerRadius import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.validations.BaseInputValidation import com.navi.naviwidgets.validations.PercentageUpperRangeValidation @@ -38,7 +39,6 @@ import com.naviapp.homeloandigital.posteligibility.fragment.HomeLoanSanctionLett import com.naviapp.utils.Constants import com.naviapp.utils.Constants.LOAN_ACTION_TYPE import com.naviapp.utils.formatCurrency -import com.naviapp.utils.setCornerRadius import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/app/src/main/java/com/naviapp/homeloandigital/landingpage/fragment/HomeLoanLandingPageFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/landingpage/fragment/HomeLoanLandingPageFragment.kt new file mode 100644 index 0000000000..4b8646a566 --- /dev/null +++ b/app/src/main/java/com/naviapp/homeloandigital/landingpage/fragment/HomeLoanLandingPageFragment.kt @@ -0,0 +1,233 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.naviapp.homeloandigital.landingpage.fragment + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.navi.base.model.CtaData +import com.navi.base.model.NaviBenefitsItemClick +import com.navi.base.model.NaviClickAction +import com.navi.base.model.NaviWidgetClickWithCtaData +import com.navi.base.utils.BaseUtils +import com.navi.common.utils.observeNullable +import com.navi.insurance.util.slideViewFromBottom +import com.navi.naviwidgets.adapters.NaviAdapter +import com.navi.naviwidgets.base.ui.IconTitleDescriptionInfoCtaBottomSheet +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.viewholder.ViewHolderFactoryImpl +import com.naviapp.R +import com.naviapp.analytics.utils.NaviAnalytics +import com.naviapp.common.listeners.BackListener +import com.naviapp.common.listeners.TopBackListener +import com.naviapp.databinding.FragmentHomeLoanLandingPageBinding +import com.naviapp.homeloandigital.common.ui.activity.Navigator +import com.naviapp.homeloandigital.common.ui.customview.TopNavigationHeaderInterface +import com.naviapp.homeloandigital.common.ui.fragment.BaseHomeLoanFragment +import com.naviapp.homeloandigital.landingpage.viewmodel.HomeLoanLandingPageFragmentVM +import com.naviapp.homeloandigital.models.FormFooter +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class HomeLoanLandingPageFragment : BaseHomeLoanFragment(), TopBackListener, BackListener, + WidgetCallback { + + private lateinit var binding: FragmentHomeLoanLandingPageBinding + private val hlLandingPageEventTracker = NaviAnalytics.naviAnalytics.HomeLoanLandingPageEvent() + private val viewModel by viewModels() + private var listener: TopNavigationHeaderInterface? = null + private val contentAdapter = + NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) + + private val scrollListener: RecyclerView.OnScrollListener = + object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + val startIndex = + (binding.recycleView.layoutManager as? LinearLayoutManager) + ?.findFirstVisibleItemPosition() + if (startIndex != null && startIndex != RecyclerView.NO_POSITION) { + if (startIndex > 0) { + slideViewFromBottom(binding.hlLandingPageFooter.landingPageFooterContainer) + } else { + binding.hlLandingPageFooter.landingPageFooterContainer.visibility = + View.GONE + } + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + super.onCreateView(inflater, container, savedInstanceState) + binding = FragmentHomeLoanLandingPageBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + hlLandingPageEventTracker.onScreenLandingEvent( + LANDING_PAGE, + isLoggedIn = BaseUtils.isUserLoggedIn() + ) + initUI() + addObservers() + fetchLandingPageResponse() + } + + override fun onAttach(context: Context) { + super.onAttach(context) + listener = context as? TopNavigationHeaderInterface + } + + override fun getLifeCycle(): Lifecycle = lifecycle + + private fun fetchLandingPageResponse() { + showLoader() + viewModel.fetchLandingPageResponse() + } + + private fun initUI() { + initError(viewModel) + binding.hlLandingPageFooter.footerCtaTitle.setOnClickListener { + navigateTo(viewModel.landingPageResponse.value?.footer?.nextCta, false) + } + } + + private fun addObservers() { + viewModel.landingPageResponse.observeNullable(viewLifecycleOwner) { response -> + hideLoader() + binding.response = response + response?.let { data -> + data.header?.let { + addMetaDataToQueryParam(it.metaData) + setDataToLatencyMapper(NEW_HL_LANDING_PAGE_TIME) + listener?.apply { + setHeaderBackgroundColor(R.color.white) + setBackIcon(R.drawable.ic_arrow_left_black) + setHeaderTextColor(R.color.outrageous_orange) + setDividerVisibility(View.GONE) + setBackIconPadding(8, 8, 8, 8) + setHelpAndCallIconVisibility( + it.showHelpIcon, it.showRequestCallbackIcon, it.helpBottomSheet + ) + } + + } + response.content?.let { initContentAdapter(it.widgets) } + response.footer?.let { footer -> + setUpFooter(footer) + } + } + } + } + + private fun setUpFooter(footer: FormFooter) { + binding.hlLandingPageFooter.apply { + footerCtaTitle.text = + footer.nextCta?.title ?: getString( + R.string.check_loan_offer + ) + footerDivider.visibility = View.GONE + landingPageFooterContainer.background = ContextCompat.getDrawable( + landingPageFooterContainer.context, + R.drawable.bottom_sheet_background_16 + ) + } + } + + private fun initContentAdapter(widgets: List?) { + widgets?.let { list -> + binding.recycleView.apply { + context?.let { + layoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + contentAdapter.list = list + adapter = contentAdapter + addOnScrollListener(scrollListener) + } + } + } + } + + private fun navigateTo(cta: CtaData?, finish: Boolean = true) { + val navigator = activity + if (navigator is Navigator) { + navigator.navigateTo(cta, finish = finish) + } + } + + override fun onTopBackPressed() { + viewModel.landingPageResponse.value?.header?.backCta?.let { + navigateTo(it) + } + } + + override fun onBackPressed() { + navigateTo(viewModel.landingPageResponse.value?.header?.backCta) + } + + override fun onClick(naviClickAction: NaviClickAction) { + when (naviClickAction) { + is CtaData -> { + navigateTo(naviClickAction) + } + is NaviBenefitsItemClick -> { + hlLandingPageEventTracker.onBenefitsCardClicked(naviClickAction.ctaData) + naviClickAction.ctaData?.url?.let { + if (it.contains(BOTTOM_SHEET, true)) { + viewModel.getBottomSheetData(naviClickAction.position) + ?.let { bottomSheetData -> + IconTitleDescriptionInfoCtaBottomSheet.newInstance(bottomSheetData) + .also { bottomSheet -> + if (!isBottomSheetVisible( + IconTitleDescriptionInfoCtaBottomSheet.TAG + ) + ) safelyShowBottomSheet( + bottomSheet, IconTitleDescriptionInfoCtaBottomSheet.TAG + ) + } + } + } + } + } + is NaviWidgetClickWithCtaData -> { + hlLandingPageEventTracker.onVideoCardClicked(naviClickAction.ctaData) + navigateTo(naviClickAction.ctaData, finish = false) + } + } + } + + override val hlScreenName: String + get() = NaviAnalytics.HL_LANDING_PAGE + + override val screenName: String + get() = "" + + companion object { + private const val BOTTOM_SHEET = "bottomsheet" + private const val LANDING_PAGE = "landing_page" + private const val NEW_HL_LANDING_PAGE_TIME = "New_HL_Landing_Page_Time" + + fun newInstance(arguments: Bundle?) = HomeLoanLandingPageFragment().apply { + this.arguments = arguments + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/homeloandigital/landingpage/model/HomeLoanLandingPageResponse.kt b/app/src/main/java/com/naviapp/homeloandigital/landingpage/model/HomeLoanLandingPageResponse.kt new file mode 100644 index 0000000000..1d3ddbb8dc --- /dev/null +++ b/app/src/main/java/com/naviapp/homeloandigital/landingpage/model/HomeLoanLandingPageResponse.kt @@ -0,0 +1,18 @@ +package com.naviapp.homeloandigital.landingpage.model + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.models.response.TextFieldData +import com.naviapp.homeloandigital.models.FormFooter +import com.naviapp.homeloandigital.models.FormHeader + +data class HLLandingPageResponse( + @SerializedName("header") var header: FormHeader? = null, + @SerializedName("content") val content: HLLandingPageContent? = null, + @SerializedName("footer") val footer: FormFooter? = null +) + +data class HLLandingPageContent( + @SerializedName("widgets") val widgets: List? = null, + @SerializedName("infoProviderText") val infoProviderText: TextFieldData? = null +) diff --git a/app/src/main/java/com/naviapp/homeloandigital/landingpage/repository/HomeLoanLandingPageRepository.kt b/app/src/main/java/com/naviapp/homeloandigital/landingpage/repository/HomeLoanLandingPageRepository.kt new file mode 100644 index 0000000000..02fd0e5946 --- /dev/null +++ b/app/src/main/java/com/naviapp/homeloandigital/landingpage/repository/HomeLoanLandingPageRepository.kt @@ -0,0 +1,16 @@ +package com.naviapp.homeloandigital.landingpage.repository + +import com.navi.common.network.models.RepoResult +import com.navi.common.network.retrofit.ResponseCallback +import com.naviapp.homeloandigital.landingpage.model.HLLandingPageResponse +import com.naviapp.network.retrofit.RetrofitService +import javax.inject.Inject + +class HomeLoanLandingPageRepository +@Inject +constructor(private val retrofitService: RetrofitService) : ResponseCallback() { + + suspend fun fetchLandingPageResponse(): RepoResult { + return apiResponseCallback(retrofitService.fetchHomeLoanLandingPageResponse()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/homeloandigital/landingpage/viewmodel/HomeLoanLandingPageFragmentVM.kt b/app/src/main/java/com/naviapp/homeloandigital/landingpage/viewmodel/HomeLoanLandingPageFragmentVM.kt new file mode 100644 index 0000000000..84da4b47fd --- /dev/null +++ b/app/src/main/java/com/naviapp/homeloandigital/landingpage/viewmodel/HomeLoanLandingPageFragmentVM.kt @@ -0,0 +1,49 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ +package com.naviapp.homeloandigital.landingpage.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.navi.common.viewmodel.BaseVM +import com.navi.naviwidgets.models.response.NaviBenefitBottomSheetData +import com.navi.naviwidgets.models.response.ProductBenefitsGridWidget +import com.naviapp.homeloandigital.landingpage.model.HLLandingPageResponse +import com.naviapp.homeloandigital.landingpage.repository.HomeLoanLandingPageRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class HomeLoanLandingPageFragmentVM @Inject constructor(private val repository: HomeLoanLandingPageRepository) : + BaseVM() { + + private val _landingPageResponse = MutableLiveData() + val landingPageResponse: LiveData + get() = _landingPageResponse + + fun fetchLandingPageResponse() = + viewModelScope.launch { + val response = repository.fetchLandingPageResponse() + if (response.error == null && response.errors.isNullOrEmpty()) { + _landingPageResponse.value = response.data + } else { + setErrorData(response.errors, response.error) + } + } + + fun getBottomSheetData(position: Int): NaviBenefitBottomSheetData? { + landingPageResponse.value?.content?.widgets?.let { + for (widget in it) { + if (widget is ProductBenefitsGridWidget) { + return widget.productBenefitsGridWidgetData?.benefitsGridItems?.get(position)?.bottomSheet + } + } + } + return null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/homeloandigital/models/response/HomeLoanPropertyDocsStatusResponse.kt b/app/src/main/java/com/naviapp/homeloandigital/models/response/HomeLoanPropertyDocsStatusResponse.kt index 571ba7fb24..cb3fde0ddb 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/models/response/HomeLoanPropertyDocsStatusResponse.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/models/response/HomeLoanPropertyDocsStatusResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanPropertyDocSubCategoryAdapter.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanPropertyDocSubCategoryAdapter.kt index c542ef7aba..018b182277 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanPropertyDocSubCategoryAdapter.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanPropertyDocSubCategoryAdapter.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -22,18 +22,18 @@ import com.naviapp.utils.isValidIndex class HomeLoanPropertyDocSubCategoryAdapter( private val docSubCategoryList: List, private val navigator: Navigator? -) : - RecyclerView.Adapter() { +) : RecyclerView.Adapter() { override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): HomeLoanPropertyDocSubCategoryVH { - val binding: ViewHlPropertyDocsSubCategoryBinding = DataBindingUtil.inflate( - LayoutInflater.from(parent.context), - R.layout.view_hl_property_docs_sub_category, - parent, - false - ) + val binding: ViewHlPropertyDocsSubCategoryBinding = + DataBindingUtil.inflate( + LayoutInflater.from(parent.context), + R.layout.view_hl_property_docs_sub_category, + parent, + false + ) binding.navigator = navigator return HomeLoanPropertyDocSubCategoryVH(binding) } @@ -42,8 +42,8 @@ class HomeLoanPropertyDocSubCategoryAdapter( if (!isValidIndex(position, itemCount)) return holder.binding.subCategoryData = docSubCategoryList[position] holder.binding.descTv.setTextFieldData(docSubCategoryList[position].subtitle) - if (position == (docSubCategoryList.size - 1)) holder.binding.divider.visibility = - View.INVISIBLE + if (position == (docSubCategoryList.size - 1)) + holder.binding.divider.visibility = View.INVISIBLE } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanUploadDocumentsAdapter.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanUploadDocumentsAdapter.kt index 8cdc17c857..b92da6ab56 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanUploadDocumentsAdapter.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/adapter/HomeLoanUploadDocumentsAdapter.kt @@ -26,10 +26,7 @@ import com.naviapp.databinding.ViewHlDocumentUploadBinding import com.naviapp.homeloandigital.posteligibility.fragment.HomeLoanUploadDocumentsFragment import com.naviapp.models.response.HomeLoanUploadItemType import com.naviapp.models.response.HomeLoanUploadedDocData -import com.naviapp.utils.DownloadUtil -import com.naviapp.utils.IconUtils -import com.naviapp.utils.downloadsDirUri -import com.naviapp.utils.isValidIndex +import com.naviapp.utils.* import java.net.URI class HomeLoanUploadDocumentsAdapter( diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanAutoDebitFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanAutoDebitFragment.kt index 90d4ba26ec..18976d3970 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanAutoDebitFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanAutoDebitFragment.kt @@ -27,6 +27,7 @@ import com.navi.common.firebasedb.FirebaseStatusType import com.navi.common.firebasedb.MANDATE import com.navi.common.firebasedb.MANDATE_COMPLETE import com.navi.common.utils.* +import com.navi.common.utils.setCornerRadius import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.utils.setBackgroundColor import com.naviapp.R @@ -51,7 +52,6 @@ import com.naviapp.personalloan.getloan.helpers.EnachStub import com.naviapp.utils.Constants import com.naviapp.utils.ifLet import com.naviapp.utils.orValue -import com.naviapp.utils.setCornerRadius import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanSanctionLetterFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanSanctionLetterFragment.kt index f22eb09355..510a0823b5 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanSanctionLetterFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanSanctionLetterFragment.kt @@ -22,9 +22,9 @@ import com.navi.base.model.CtaData import com.navi.base.model.LineItem import com.navi.common.firebasedb.FirebaseDataHelper import com.navi.common.firebasedb.FirebaseStatusType -import com.navi.common.utils.ApiPollScheduler -import com.navi.common.utils.observeNonNull -import com.navi.common.utils.observeNullable +import com.navi.common.utils.* +import com.navi.common.utils.makePartOfTextBold +import com.navi.common.utils.setCornerRadius import com.navi.naviwidgets.extensions.setTextFieldData import com.navi.naviwidgets.utils.FORWARD_SLASH import com.naviapp.R @@ -47,6 +47,8 @@ import com.naviapp.homeloandigital.posteligibility.viewmodel.HomeLoanSanctionLet import com.naviapp.models.response.ItemWithTextAndIcon import com.naviapp.models.response.ViewMarginResponse import com.naviapp.utils.* +import com.naviapp.utils.Constants +import com.naviapp.utils.Constants.EMPTY import com.naviapp.utils.Constants.LOAN_ACTION_TYPE import dagger.hilt.android.AndroidEntryPoint import java.net.URI diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanUploadDocumentsFragment.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanUploadDocumentsFragment.kt index 96d50b6964..73cff6cce7 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanUploadDocumentsFragment.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/fragment/HomeLoanUploadDocumentsFragment.kt @@ -291,6 +291,13 @@ class HomeLoanUploadDocumentsFragment : BaseHomeLoanFragment(), BackListener, To ) } } + uploadDocumentViewModel.homeLoanDocumentDeleteAllLiveData.observe(viewLifecycleOwner) { + it.forEach { id -> + (binding.uploadDocumentGrid.adapter as? HomeLoanUploadDocumentsAdapter)?.removeData( + id + ) + } + } } private fun initListeners() { @@ -322,6 +329,17 @@ class HomeLoanUploadDocumentsFragment : BaseHomeLoanFragment(), BackListener, To ) } } + binding.downloadAll.setOnClickListener { + Toast.makeText(context, getString(R.string.downloading), Toast.LENGTH_LONG).show() + uploadDocumentViewModel.getRejectedDocs().forEach { homeLoanUploadedDocData -> + val destinationPath = + cacheDirUri(REJECTED_DOC.plus(homeLoanUploadedDocData?.referenceId)) + DownloadUtil.download( + Uri.parse(homeLoanUploadedDocData?.uri), + URI.create(destinationPath) + ) + } + } } private fun deleteDocument(item: HomeLoanUploadedDocData, position: Int) { diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/repository/HomeLoanPropertyDocumentStatusRepo.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/repository/HomeLoanPropertyDocumentStatusRepo.kt index 38a8295036..7141c8cc33 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/repository/HomeLoanPropertyDocumentStatusRepo.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/repository/HomeLoanPropertyDocumentStatusRepo.kt @@ -1,26 +1,28 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ package com.naviapp.homeloandigital.posteligibility.repository -import com.naviapp.homeloandigital.models.response.HomeLoanPropertyDocsStatusResponse import com.navi.common.model.RepoResult +import com.naviapp.homeloandigital.models.response.HomeLoanPropertyDocsStatusResponse import com.naviapp.network.retrofit.ResponseCallback import com.naviapp.network.retrofit.RetrofitService import javax.inject.Inject -class HomeLoanPropertyDocumentStatusRepo @Inject constructor(private val retrofitService: RetrofitService) : - ResponseCallback() { +class HomeLoanPropertyDocumentStatusRepo +@Inject +constructor(private val retrofitService: RetrofitService) : ResponseCallback() { - suspend fun fetchPropertyDocsStatus(queryMap: HashMap): RepoResult = + suspend fun fetchPropertyDocsStatus( + queryMap: HashMap + ): RepoResult = apiResponseCallback(retrofitService.fetchPropertyDocsStatus(queryMap)) suspend fun submitHomeLoanDocuments(loanApplicationId: String): RepoResult { return apiResponseCallback(retrofitService.submitHomeLoanDocuments(loanApplicationId, null)) } - } diff --git a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/viewmodel/HomeLoanDocumentUploadVM.kt b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/viewmodel/HomeLoanDocumentUploadVM.kt index a7908932b7..ccec617c14 100644 --- a/app/src/main/java/com/naviapp/homeloandigital/posteligibility/viewmodel/HomeLoanDocumentUploadVM.kt +++ b/app/src/main/java/com/naviapp/homeloandigital/posteligibility/viewmodel/HomeLoanDocumentUploadVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -20,12 +20,13 @@ import com.naviapp.models.response.HomeLoanDocumentUploadResponse import com.naviapp.models.response.HomeLoanUploadItemType import com.naviapp.models.response.HomeLoanUploadedDocData import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.launch import javax.inject.Inject +import kotlinx.coroutines.launch @HiltViewModel -class HomeLoanDocumentUploadVM @Inject constructor(private val repository: HomeLoanDocumentUploadRepository) : - BaseVM() { +class HomeLoanDocumentUploadVM +@Inject +constructor(private val repository: HomeLoanDocumentUploadRepository) : BaseVM() { private val _homeLoanDocumentUploadResponse = MutableLiveData() val homeLoanDocumentUploadResponse: LiveData @@ -77,11 +78,12 @@ class HomeLoanDocumentUploadVM @Inject constructor(private val repository: HomeL val response = repository.sendHomeLoanDocumentUploadDetails(loanApplicationId, body, contextKey) if (response.error == null && response.errors.isNullOrEmpty()) { - _homeLoanSendDocumentResponse.value = HomeLoanDocumentPostResponse( - referenceId = response.data?.referenceId, - saReferenceId = documentReferenceId, - uri = response.data?.uri - ) + _homeLoanSendDocumentResponse.value = + HomeLoanDocumentPostResponse( + referenceId = response.data?.referenceId, + saReferenceId = documentReferenceId, + uri = response.data?.uri + ) } else { _homeLoanDocUploadFailed.value = documentReferenceId } @@ -112,12 +114,13 @@ class HomeLoanDocumentUploadVM @Inject constructor(private val repository: HomeL val documentDeleteIds = mutableListOf() documentList?.forEachIndexed { index, homeLoanUploadedDocData -> homeLoanUploadedDocData?.run { - if (referenceId.isNotNullAndNotEmpty() && documentStatus != HomeLoanUploadDocumentsFragment.DOCUMENT_VALIDATED + if ( + referenceId.isNotNullAndNotEmpty() && + documentStatus != HomeLoanUploadDocumentsFragment.DOCUMENT_VALIDATED ) { documentDeleteIds.add(referenceId!!) } } - } viewModelScope.launch { val response = @@ -143,9 +146,8 @@ class HomeLoanDocumentUploadVM @Inject constructor(private val repository: HomeL fun getRejectedDocs(): List { return homeLoanDocumentUploadResponse.value?.content?.uploadDetails?.rejectedDocs?.map { - it?.apply { - type = HomeLoanUploadItemType.REJECTED_DOCUMENT - } - } ?: emptyList() + it?.apply { type = HomeLoanUploadItemType.REJECTED_DOCUMENT } + } + ?: emptyList() } } diff --git a/app/src/main/java/com/naviapp/models/DashboardPolicyBenefitData.kt b/app/src/main/java/com/naviapp/models/DashboardPolicyBenefitData.kt index 61b6844232..7ddd979134 100644 --- a/app/src/main/java/com/naviapp/models/DashboardPolicyBenefitData.kt +++ b/app/src/main/java/com/naviapp/models/DashboardPolicyBenefitData.kt @@ -1,3 +1,11 @@ +/* + * + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.models import android.os.Parcelable @@ -11,23 +19,17 @@ import kotlinx.android.parcel.Parcelize @Parcelize data class DashboardPolicyBenefitData( - @SerializedName("actionData") - val actionData: ActionData? = null, + @SerializedName("actionData") val actionData: ActionData? = null, @SerializedName("policies") val listOfPolicyBenefits: List? = null ) : HomeLoanSubStepResponse(), Parcelable @Parcelize data class PolicyBenefitData( - @SerializedName("policyId") - val policyId: String? = null, - @SerializedName("sumInsured") - val sumInsured: Double? = null, - @SerializedName("numberOfMembersInsured") - val numberOfMembersInsured: Int? = null, - @SerializedName("status") - val status: String? = null, - @SerializedName("statusAttribute") - val statusAttribute: StatusAttribute? = null, + @SerializedName("policyId") val policyId: String? = null, + @SerializedName("sumInsured") val sumInsured: Double? = null, + @SerializedName("numberOfMembersInsured") val numberOfMembersInsured: Int? = null, + @SerializedName("status") val status: String? = null, + @SerializedName("statusAttribute") val statusAttribute: StatusAttribute? = null, @SerializedName("emiDue") val policyPaymentData: DashboardPolicyPaymentData? = null ) : Parcelable, RadioButtonModel { override var selected: Boolean? = null @@ -35,28 +37,19 @@ data class PolicyBenefitData( @Parcelize data class StatusAttribute( - @SerializedName("title") - val title: TextWithStyle? = null, - @SerializedName("bgColor") - val bgColor: String? = null, - @SerializedName("iconCode") - val iconCode: String? = null + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("iconCode") val iconCode: String? = null ) : Parcelable @Parcelize data class DashboardPolicyPaymentData( - @SerializedName("title") - val title: TextWithStyle? = null, - @SerializedName("subTitle") - val subTitle: TextWithStyle? = null, - @SerializedName("dueDate") - val dueDate: String? = null, - @SerializedName("installmentDueDate") - val installmentDueDate: String? = null, - @SerializedName("emi") - val emi: Money? = null, - @SerializedName("actionData") - val actionData: ActionData? = null, + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("subTitle") val subTitle: TextWithStyle? = null, + @SerializedName("dueDate") val dueDate: String? = null, + @SerializedName("installmentDueDate") val installmentDueDate: String? = null, + @SerializedName("emi") val emi: Money? = null, + @SerializedName("actionData") val actionData: ActionData? = null, ) : Parcelable enum class PolicyBenefitStatus { @@ -64,4 +57,5 @@ enum class PolicyBenefitStatus { IN_PROGRESS, GRACE_PERIOD, NOT_APPLICABLE -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/naviapp/models/EMIDateChangeResponse.kt b/app/src/main/java/com/naviapp/models/EMIDateChangeResponse.kt index 1b741be98d..e2d8f70a44 100644 --- a/app/src/main/java/com/naviapp/models/EMIDateChangeResponse.kt +++ b/app/src/main/java/com/naviapp/models/EMIDateChangeResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -12,43 +12,29 @@ import com.naviapp.homeloandigital.models.FormFooter import com.naviapp.homeloandigital.models.FormHeader data class EMIDateChangeResponse( - @SerializedName("header") - val header: FormHeader? = null, - @SerializedName("content") - val content: EMIDateChangeContent? = null, - @SerializedName("footer") - val footer: FormFooter? = null + @SerializedName("header") val header: FormHeader? = null, + @SerializedName("content") val content: EMIDateChangeContent? = null, + @SerializedName("footer") val footer: FormFooter? = null ) data class EMIDateChangeContent( - @SerializedName("title") - val title: KeyValueResponse? = null, - @SerializedName("chooseDateHeader") - val chooseDateHeader: String? = null, - @SerializedName("calendarConfig") - val calendarConfig: CalendarConfig? = null, - @SerializedName("reasonConfig") - val reasonConfig: ReasonConfig? = null + @SerializedName("title") val title: KeyValueResponse? = null, + @SerializedName("chooseDateHeader") val chooseDateHeader: String? = null, + @SerializedName("calendarConfig") val calendarConfig: CalendarConfig? = null, + @SerializedName("reasonConfig") val reasonConfig: ReasonConfig? = null ) data class CalendarConfig( - @SerializedName("header") - val header: String? = null, - @SerializedName("columnCount") - val columnCount: Int? = null, - @SerializedName("defaultBgColor") - val defaultBgColor: String? = null, - @SerializedName("defaultFontColor") - val defaultFontColor: String? = null, - @SerializedName("availabeEmiDates") - val availabeEmiDates: List? = null + @SerializedName("header") val header: String? = null, + @SerializedName("columnCount") val columnCount: Int? = null, + @SerializedName("defaultBgColor") val defaultBgColor: String? = null, + @SerializedName("defaultFontColor") val defaultFontColor: String? = null, + @SerializedName("availabeEmiDates") val availabeEmiDates: List? = null ) data class ReasonConfig( - @SerializedName("header") - val header: String? = null, - @SerializedName("hint") - val hint: String? = null, - @SerializedName("validationError") - val validationError: String? = null + @SerializedName("header") val header: String? = null, + @SerializedName("hint") val hint: String? = null, + @SerializedName("warning") val warningText: String? = null, + @SerializedName("validationError") val validationError: String? = null ) diff --git a/app/src/main/java/com/naviapp/models/Offer.kt b/app/src/main/java/com/naviapp/models/Offer.kt index 1b29533767..adc25e502f 100644 --- a/app/src/main/java/com/naviapp/models/Offer.kt +++ b/app/src/main/java/com/naviapp/models/Offer.kt @@ -72,7 +72,8 @@ data class SliderData( @Parcelize data class MicroTicketLoanData( @SerializedName("title") val title: String? = null, - @SerializedName("microTicketLoanCardData") val microTicketLoanCardData: MicroTicketLoanCardData? = null + @SerializedName("microTicketLoanCardData") + val microTicketLoanCardData: MicroTicketLoanCardData? = null ) : Parcelable @Parcelize diff --git a/app/src/main/java/com/naviapp/models/UserDetail.kt b/app/src/main/java/com/naviapp/models/UserDetail.kt index f72648e310..864d80c6f2 100644 --- a/app/src/main/java/com/naviapp/models/UserDetail.kt +++ b/app/src/main/java/com/naviapp/models/UserDetail.kt @@ -1,6 +1,7 @@ /* - * * - * * Copyright (c) 2020 . All rights reserved @Navi + * + * * Copyright © 2020-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -34,7 +35,8 @@ data class UserDetail( @SerializedName("toast") val toast: ToastWidget? = null, @SerializedName("panInfo") val panInfo: PanInfo? = null, @SerializedName("panToolTip") val panToolTip: String? = null, - @SerializedName("dataSafetyBottomSheet") val dataSafetyBottomSheet: InfoBottomSheetConfig? = null + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null ) data class FinoramicStatus( @@ -46,4 +48,4 @@ data class FinoramicStatus( data class PanInfo( @SerializedName("hint") val hint: String? = null, @SerializedName("title") val title: String? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/models/request/UniversalBottomSheetData.kt b/app/src/main/java/com/naviapp/models/request/UniversalBottomSheetData.kt index e72c44f48a..f138776431 100644 --- a/app/src/main/java/com/naviapp/models/request/UniversalBottomSheetData.kt +++ b/app/src/main/java/com/naviapp/models/request/UniversalBottomSheetData.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.models.request import com.google.gson.annotations.SerializedName @@ -6,21 +13,14 @@ import com.navi.design.textview.model.TextWithStyle import java.io.Serializable data class UniversalBottomSheetData( - @SerializedName("title") - val title: TextWithStyle? = null, - @SerializedName("count") - val count: String? = null, - @SerializedName("items") - val items: List? = null, - @SerializedName("actionData") - val actionData: ActionData? = null -): Serializable + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("count") val count: String? = null, + @SerializedName("items") val items: List? = null, + @SerializedName("actionData") val actionData: ActionData? = null +) : Serializable data class KeyValueRowData( - @SerializedName("key") - val key: TextWithStyle? = null, - @SerializedName("value") - val value: TextWithStyle? = null, - @SerializedName("showDivider") - val showDivider: Boolean? = null -) \ No newline at end of file + @SerializedName("key") val key: TextWithStyle? = null, + @SerializedName("value") val value: TextWithStyle? = null, + @SerializedName("showDivider") val showDivider: Boolean? = null +) diff --git a/app/src/main/java/com/naviapp/models/response/AdditionalData.kt b/app/src/main/java/com/naviapp/models/response/AdditionalData.kt index e1bbfbe20e..0391504c14 100644 --- a/app/src/main/java/com/naviapp/models/response/AdditionalData.kt +++ b/app/src/main/java/com/naviapp/models/response/AdditionalData.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.models.response /* * @@ -10,7 +17,6 @@ import com.google.gson.annotations.SerializedName import com.navi.common.model.Money import com.naviapp.models.Tenure - interface AdditionalData data class LoanDetailsV2AdditionData( @@ -30,4 +36,4 @@ data class LoanDetailsV2AdditionData( @SerializedName("loanTenureProgressPercentage") var loanTenureProgressPercentage: Double? = 1.0, @SerializedName("email") var email: String? = null, @SerializedName("centerDialog") val centerDialog: GeneralGreetingResponse? = null -) : AdditionalData \ No newline at end of file +) : AdditionalData diff --git a/app/src/main/java/com/naviapp/models/response/BannerInfo.kt b/app/src/main/java/com/naviapp/models/response/BannerInfo.kt index b0f232a235..7c6fb2c310 100644 --- a/app/src/main/java/com/naviapp/models/response/BannerInfo.kt +++ b/app/src/main/java/com/naviapp/models/response/BannerInfo.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -21,7 +21,8 @@ data class BannerInfo( @SerializedName("iconCode") val iconCode: String? = null, @SerializedName("offerUpgradeBenefits") val offerUpgradeBenefits: List? = null, @SerializedName("cta") val cta: CtaData? = null, - @SerializedName("inactiveCoApplicants") val inactiveCoApplicants: List? = null, + @SerializedName("inactiveCoApplicants") + val inactiveCoApplicants: List? = null, @SerializedName("info") val info: InfoContent? = null, @SerializedName("flowType") val flowType: String? = null, @SerializedName("subCards") val subCards: List? = null, diff --git a/app/src/main/java/com/naviapp/models/response/ConsentResponse.kt b/app/src/main/java/com/naviapp/models/response/ConsentResponse.kt index 7718a30dde..a806e588a3 100644 --- a/app/src/main/java/com/naviapp/models/response/ConsentResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/ConsentResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -20,4 +20,4 @@ data class ConsentResponse( @SerializedName("consent_handle") val consentHandle: String? = null, @SerializedName("consent_status") val consentStatus: String? = null, @SerializedName("cta") val cta: CtaData? = null -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/com/naviapp/models/response/DisbursementDetailsResponse.kt b/app/src/main/java/com/naviapp/models/response/DisbursementDetailsResponse.kt index 3c50cd3f25..e9a3548377 100644 --- a/app/src/main/java/com/naviapp/models/response/DisbursementDetailsResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/DisbursementDetailsResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -39,32 +39,34 @@ data class DisbursementDetails( @SerializedName("editBankRetriesLeft") val editBankRetriesLeft: Int? = null, @SerializedName("autoPayOptions") val autoPayOptions: List? = null, @SerializedName("accountHolderDeclaration") val accountHolderDeclaration: String? = null, - @SerializedName("isAccountHolderDeclarationSet") val isAccountHolderDeclarationSet: Boolean? = null, + @SerializedName("isAccountHolderDeclarationSet") + val isAccountHolderDeclarationSet: Boolean? = null, @SerializedName("header") val headerTitle: String? = null, @SerializedName("note") val note: LastUpdateData? = null, - @SerializedName("lastMandateInformation") val lastMandateInformation: LastMandateInformation? = null, + @SerializedName("lastMandateInformation") + val lastMandateInformation: LastMandateInformation? = null, @SerializedName("skipMandate") val skipMandate: Boolean? = null, @SerializedName("verifiedBannerData") val verifiedBannerData: VerifiedBannerData? = null, @SerializedName("pennyDropFailureData") val pennyDropFailureData: PennyDropFailureData? = null, - @SerializedName("skipMandateSection") val skipMandateSectionData: SkipMandateSectionData? = null, + @SerializedName("skipMandateSection") + val skipMandateSectionData: SkipMandateSectionData? = null, @SerializedName("fullScreenErrorInfo") val fullScreenErrorInfo: FullScreenErrorInfo? = null, @SerializedName("headersConfig") val headersConfig: BankDetailsHeadersConfig? = null, - @SerializedName("styledAccountHolderName") val styledAccountHolderName: StyledTextWithIconCode? = null, - @SerializedName("bankDetailsAutoDebitConfig") val bankDetailsAutoDebitConfig: BankDetailsAutoPayData? = null, - @SerializedName("dataSafetyBottomSheet") val dataSafetyBottomSheet: InfoBottomSheetConfig? = null, - @SerializedName("autopaySetupSuccessMessage") val autoPaySuccessMessage : String? = null + @SerializedName("styledAccountHolderName") + val styledAccountHolderName: StyledTextWithIconCode? = null, + @SerializedName("bankDetailsAutoDebitConfig") + val bankDetailsAutoDebitConfig: BankDetailsAutoPayData? = null, + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null, + @SerializedName("autopaySetupSuccessMessage") val autoPaySuccessMessage: String? = null ) : Parcelable @Parcelize open class FullScreenErrorInfo( - @SerializedName("title") - val title: String? = null, - @SerializedName("iconCode") - val iconCode: String? = null, - @SerializedName("subtitle") - val subTitle: String? = null, - @SerializedName("cta") - val cta: CtaData? = null + @SerializedName("title") val title: String? = null, + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("subtitle") val subTitle: String? = null, + @SerializedName("cta") val cta: CtaData? = null ) : Parcelable @Parcelize @@ -85,9 +87,12 @@ data class VerifiedBannerData( @Parcelize data class BankDetailsHeadersConfig( - @SerializedName("disbursementAmountHeader") val disbursementAmountHeader: StyledTextWithIconCode? = null, - @SerializedName("bankNameDisclaimerHeader") val bankNameDisclaimerHeader: StyledTextWithIconCode? = null, - @SerializedName("bankSearchDisclaimerHeader") val bankSearchDisclaimerHeader: StyledTextWithIconCode? = null + @SerializedName("disbursementAmountHeader") + val disbursementAmountHeader: StyledTextWithIconCode? = null, + @SerializedName("bankNameDisclaimerHeader") + val bankNameDisclaimerHeader: StyledTextWithIconCode? = null, + @SerializedName("bankSearchDisclaimerHeader") + val bankSearchDisclaimerHeader: StyledTextWithIconCode? = null ) : Parcelable @Parcelize @@ -110,7 +115,6 @@ data class BankDetailsAutoPayDetailsCard( @SerializedName("items") val items: List? = null ) : Parcelable - @Parcelize data class BankDetailsAutoPayBankCard( @SerializedName("title") val title: String? = null, @@ -119,7 +123,6 @@ data class BankDetailsAutoPayBankCard( @SerializedName("description") val description: String? = null ) : Parcelable - @Parcelize data class PennyDropFailureData( @SerializedName("errorBottomSheet") val errorBottomSheet: PennyErrorBottomSheetData? = null, @@ -137,10 +140,10 @@ data class BankDetailsBottomOverlay( @SerializedName("subtitle") val subtitle: StyledTextWithIconCode? = null, @SerializedName("additionalData") val additionalData: PennyErrorBottomSheetData? = null, @SerializedName("remainingCount") val remainingCount: Int? = null, - @SerializedName("lastAttemptBottomSheet") val lastAttemptBottomSheet: PennyErrorBottomSheetData? = null + @SerializedName("lastAttemptBottomSheet") + val lastAttemptBottomSheet: PennyErrorBottomSheetData? = null ) : Parcelable - @Parcelize data class PennyErrorBottomSheetData( @SerializedName("title") val title: String? = null, @@ -151,9 +154,7 @@ data class PennyErrorBottomSheetData( @SerializedName("footerText") val footerText: String? = null ) : Parcelable -data class AddBankDetailsAdditionData( - @SerializedName("status") val status: String? = null -) +data class AddBankDetailsAdditionData(@SerializedName("status") val status: String? = null) data class AddBankDetailsStatusAdditionData( @SerializedName("showPennyDropFailure") val showPennyDropFailure: Boolean? = null @@ -200,4 +201,3 @@ enum class RepaymentMethod(value: String) { PAY_USING_APP("PAY_USING_APP"), SETUP_ENACH_POST_DISBURSEMENT("SETUP_ENACH_POST_DISBURSEMENT") } - diff --git a/app/src/main/java/com/naviapp/models/response/EffectiveInterestInfoResponse.kt b/app/src/main/java/com/naviapp/models/response/EffectiveInterestInfoResponse.kt index bfa29be2ae..df0834e0da 100644 --- a/app/src/main/java/com/naviapp/models/response/EffectiveInterestInfoResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/EffectiveInterestInfoResponse.kt @@ -16,8 +16,10 @@ data class EffectiveInterestInfoResponse( ) data class EffectiveInterestInfoContent( - @SerializedName("repaymentDetails") val repaymentDetails: EffectiveInterestInfoContentItem? = null, - @SerializedName("calculationCard") val calculationCard: EffectiveInterestInfoContentItem? = null, + @SerializedName("repaymentDetails") + val repaymentDetails: EffectiveInterestInfoContentItem? = null, + @SerializedName("calculationCard") + val calculationCard: EffectiveInterestInfoContentItem? = null, ) data class EffectiveInterestInfoContentItem( @@ -27,4 +29,4 @@ data class EffectiveInterestInfoContentItem( @SerializedName("annualInterestRate") val annualInterestRate: LineItem? = null, @SerializedName("interestAmount") val interestAmount: LineItem? = null, @SerializedName("effectiveInterestCost") val effectiveInterestCost: LineItem? = null, -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/models/response/Header.kt b/app/src/main/java/com/naviapp/models/response/Header.kt index 0ad754876b..f9983c106b 100644 --- a/app/src/main/java/com/naviapp/models/response/Header.kt +++ b/app/src/main/java/com/naviapp/models/response/Header.kt @@ -8,6 +8,7 @@ package com.naviapp.models.response import android.os.Parcelable import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData import com.navi.base.model.CtaData import kotlinx.android.parcel.Parcelize @@ -19,5 +20,12 @@ data class Header( @SerializedName("progress") val progress: Int? = null, @SerializedName("leftIconCode") val leftIconCode: String? = null, @SerializedName("infoCta") val infoCta: CtaData? = null, - @SerializedName("enableHelp") val enableHelp: Boolean? = null + @SerializedName("enableHelp") val enableHelp: Boolean? = null, + @SerializedName("leftIconData") val leftIconData: LeftIconData? = null, +) : Parcelable + +@Parcelize +data class LeftIconData( + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("actionData") val actionData: ActionData? = null ) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/models/response/LoanDisbursementStatusMessageResponse.kt b/app/src/main/java/com/naviapp/models/response/LoanDisbursementStatusMessageResponse.kt index 3b486edf2f..a366e57f13 100644 --- a/app/src/main/java/com/naviapp/models/response/LoanDisbursementStatusMessageResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/LoanDisbursementStatusMessageResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -17,4 +17,4 @@ data class LoanDisbursementStatusMessageResponse( @SerializedName("netDisbursalAmount") val netDisbursalAmount: Double? = null, @SerializedName("redirectCtaUrl") val redirectCtaUrl: String? = null, @SerializedName("loanAccountNumber") val loanAccountNumber: String? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/models/response/LoginResponse.kt b/app/src/main/java/com/naviapp/models/response/LoginResponse.kt index 1f9d15c04d..ce702960af 100644 --- a/app/src/main/java/com/naviapp/models/response/LoginResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/LoginResponse.kt @@ -11,5 +11,7 @@ import com.google.gson.annotations.SerializedName data class LoginResponse( @SerializedName("otpToken") val otpToken: String? = null, + @SerializedName("callEnabled") val callEnabled: Boolean? = null, + @SerializedName("phoneNumber") var phoneNumber: String? = null, @SerializedName("status") val status: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/models/response/OfferUpgradeResponse.kt b/app/src/main/java/com/naviapp/models/response/OfferUpgradeResponse.kt index 2739fafa19..3c8693585d 100644 --- a/app/src/main/java/com/naviapp/models/response/OfferUpgradeResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/OfferUpgradeResponse.kt @@ -9,9 +9,9 @@ package com.naviapp.models.response import android.os.Parcelable import com.google.gson.annotations.SerializedName -import kotlinx.android.parcel.Parcelize import com.navi.base.model.CtaData import com.navi.base.model.LineItem +import kotlinx.android.parcel.Parcelize data class OfferUpgradeResponse( @SerializedName("header") val header: Header? = null, @@ -20,8 +20,10 @@ data class OfferUpgradeResponse( ) data class OfferUpgradeDetails( - @SerializedName("loanOfferBenefitCardData") val loanOfferBenefitCardData: LoanOfferBenefitCardData? = null, - @SerializedName("offerImprovementCardsList") val offerImprovementCardsList: List? = null, + @SerializedName("loanOfferBenefitCardData") + val loanOfferBenefitCardData: LoanOfferBenefitCardData? = null, + @SerializedName("offerImprovementCardsList") + val offerImprovementCardsList: List? = null, @SerializedName("centerDialog") val centerDialog: OfferUpgradeGreetingResponse? = null, @SerializedName("popUp") val popUpInfo: PopUpInfo? = null ) @@ -30,9 +32,11 @@ data class LoanOfferBenefitCardData( @SerializedName("title") val title: String? = null, @SerializedName("iconCode") val iconCode: String? = null, @SerializedName("benefitsLineItem") val benefitsLineItem: List? = null, - @SerializedName("loanOfferUpgradedItems") val loanOfferUpgradedItems: List? = null, + @SerializedName("loanOfferUpgradedItems") + val loanOfferUpgradedItems: List? = null, @SerializedName("description") val description: String? = null, - @SerializedName("loanOfferUpgradedItemsTitle") val loanOfferUpgradedItemsTitle: LoanOfferUpgradedItemsTitle? = null + @SerializedName("loanOfferUpgradedItemsTitle") + val loanOfferUpgradedItemsTitle: LoanOfferUpgradedItemsTitle? = null ) data class OfferImprovementDocumentsCardData( @@ -92,4 +96,4 @@ data class LoanOfferUpgradedItemsTitle( @SerializedName("loanAmountTitle") val loanAmountTitle: String? = null, @SerializedName("loanAmount") val loanAmount: String? = null, @SerializedName("iconCode") val iconCode: String? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/models/response/PermissionDetailsResponse.kt b/app/src/main/java/com/naviapp/models/response/PermissionDetailsResponse.kt index cd0005d7e8..138d99ecd4 100644 --- a/app/src/main/java/com/naviapp/models/response/PermissionDetailsResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/PermissionDetailsResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -8,7 +8,7 @@ package com.naviapp.models.response import com.google.gson.annotations.SerializedName -import com.naviapp.permission.models.PermissionTile +import com.navi.common.model.permission.PermissionTile import com.naviapp.personalloanrevamp.models.InfoBottomSheetConfig data class PermissionDetailsResponse( @@ -18,6 +18,7 @@ data class PermissionDetailsResponse( ) data class PermissionDetailsContent( - @SerializedName("dataSafetyBottomSheet") val dataSafetyBottomSheet: InfoBottomSheetConfig? = null, - @SerializedName("permissionList") val permissionList : List? = null -) \ No newline at end of file + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null, + @SerializedName("permissionList") val permissionList: List? = null +) diff --git a/app/src/main/java/com/naviapp/models/response/SummaryViewResponse.kt b/app/src/main/java/com/naviapp/models/response/SummaryViewResponse.kt index 1334e634eb..2c6433c7a2 100644 --- a/app/src/main/java/com/naviapp/models/response/SummaryViewResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/SummaryViewResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -54,32 +54,19 @@ data class Ctas( ) data class RewardsInfo( - @SerializedName("iconUrl") - val iconUrl: String? = null, - @SerializedName("dividerColor") - val dividerColor: String? = null, - @SerializedName("bgColor") - val bgColor: String? = null, - @SerializedName("title", alternate = ["titleAttribute"]) - val title: NaviTextComponent? = null, - @SerializedName("enableShimmer") - val enableShimmer: Boolean? = null, - @SerializedName("tagInfo") - val tagInfo: RewardsTagInfo? = null, - @SerializedName("actionData") - val actionData: ActionData? = null, - @SerializedName("metaData") - val genericAnalytics: GenericAnalytics? = null, - @SerializedName("rewardType") - val rewardType: String? = null + @SerializedName("iconUrl") val iconUrl: String? = null, + @SerializedName("dividerColor") val dividerColor: String? = null, + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("title", alternate = ["titleAttribute"]) val title: NaviTextComponent? = null, + @SerializedName("enableShimmer") val enableShimmer: Boolean? = null, + @SerializedName("tagInfo") val tagInfo: RewardsTagInfo? = null, + @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("metaData") val genericAnalytics: GenericAnalytics? = null, + @SerializedName("rewardType") val rewardType: String? = null ) data class RewardsTagInfo( - @SerializedName("bgColor") - val bgColor: String? = null, - @SerializedName("text") - val text: String? = null, - @SerializedName("textColor") - val textColor: String? = null + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("text") val text: String? = null, + @SerializedName("textColor") val textColor: String? = null ) : Serializable - diff --git a/app/src/main/java/com/naviapp/models/response/WidgetGenericResponse.kt b/app/src/main/java/com/naviapp/models/response/WidgetGenericResponse.kt index 9f868ec18b..dfa25f0d97 100644 --- a/app/src/main/java/com/naviapp/models/response/WidgetGenericResponse.kt +++ b/app/src/main/java/com/naviapp/models/response/WidgetGenericResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -14,85 +14,52 @@ import com.navi.naviwidgets.widgets.textdisplay.Margin import kotlinx.android.parcel.Parcelize data class WidgetGenericResponse( - @SerializedName("headerWidget") - val headerWidget: List? = null, - @SerializedName("contentWidget") - val contentWidget: List? = null, - @SerializedName("footerWidget") - val footerWidget: List? = null + @SerializedName("headerWidget") val headerWidget: List? = null, + @SerializedName("contentWidget") val contentWidget: List? = null, + @SerializedName("footerWidget") val footerWidget: List? = null ) abstract class WidgetConfig( - @SerializedName("type", alternate = ["widgetName"]) - open val widgetType: String? = null, - @SerializedName("id") - val widgetId: String? = null, - @SerializedName("status") - val status: String? = null, - @SerializedName("widgetLayoutParams") - val widgetLayoutParams: WidgetConfigLayoutParams? = null + @SerializedName("type", alternate = ["widgetName"]) open val widgetType: String? = null, + @SerializedName("id") val widgetId: String? = null, + @SerializedName("status") val status: String? = null, + @SerializedName("widgetLayoutParams") val widgetLayoutParams: WidgetConfigLayoutParams? = null ) @Parcelize -data class GenericWidgetConfig( - @SerializedName("body") - val widgetBody: GenericWidgetBody? = null -) : WidgetConfig(), Parcelable +data class GenericWidgetConfig(@SerializedName("body") val widgetBody: GenericWidgetBody? = null) : + WidgetConfig(), Parcelable @Parcelize open class GenericWidgetBody( - @SerializedName("title") - val title: String? = null, - @SerializedName("imageUrl") - val imageUrl: String? = null, - @SerializedName("subTitle") - val subTitle: String? = null, - @SerializedName("items") - val items: List? = null, - @SerializedName("description") - val description: String? = null, - @SerializedName("cta") - val cta: CtaData? = null, - @SerializedName("documentUrl") - val documentUrl: String? = null, - @SerializedName("offerTag") - val offerTag : OfferTag? = null, - @SerializedName("iconCode") - val iconCode: String? = null + @SerializedName("title") val title: String? = null, + @SerializedName("imageUrl") val imageUrl: String? = null, + @SerializedName("subTitle") val subTitle: String? = null, + @SerializedName("items") val items: List? = null, + @SerializedName("description") val description: String? = null, + @SerializedName("cta") val cta: CtaData? = null, + @SerializedName("documentUrl") val documentUrl: String? = null, + @SerializedName("offerTag") val offerTag: OfferTag? = null, + @SerializedName("iconCode") val iconCode: String? = null ) : Parcelable @Parcelize data class GenericWidgetItem( - @SerializedName("type") - val itemType: String? = null, - @SerializedName("imageUrl") - val imageUrl: String? = null, - @SerializedName("subTitle") - val subTitle: String? = null, - @SerializedName("imageDetail") - val imageDetail: ImageDetail? = null, - @SerializedName("cta") - var cta: CtaData? = null + @SerializedName("type") val itemType: String? = null, + @SerializedName("imageUrl") val imageUrl: String? = null, + @SerializedName("subTitle") val subTitle: String? = null, + @SerializedName("imageDetail") val imageDetail: ImageDetail? = null, + @SerializedName("cta") var cta: CtaData? = null ) : ItemWithTextAndIcon() -data class WidgetConfigLayoutParams( - @SerializedName("margin") - val margin: Margin? = null -) +data class WidgetConfigLayoutParams(@SerializedName("margin") val margin: Margin? = null) @Parcelize data class OfferTag( - @SerializedName("bgColor") - val bgColor: String? = null, - @SerializedName("animationEnabled") - val animationEnabled: Boolean? = false, - @SerializedName("title") - val title: String? = null, - @SerializedName("offerTagText") - val offerTagText: String? = null, - @SerializedName("rightIcon") - val rightIcon: String? = null, - @SerializedName("leftIcon") - val leftIcon: String? = null, + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("animationEnabled") val animationEnabled: Boolean? = false, + @SerializedName("title") val title: String? = null, + @SerializedName("offerTagText") val offerTagText: String? = null, + @SerializedName("rightIcon") val rightIcon: String? = null, + @SerializedName("leftIcon") val leftIcon: String? = null, ) : Parcelable - diff --git a/app/src/main/java/com/naviapp/models/response/WorkDetailsContent.kt b/app/src/main/java/com/naviapp/models/response/WorkDetailsContent.kt index efa53393de..188b8241ca 100644 --- a/app/src/main/java/com/naviapp/models/response/WorkDetailsContent.kt +++ b/app/src/main/java/com/naviapp/models/response/WorkDetailsContent.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -8,10 +8,10 @@ package com.naviapp.models.response import com.google.gson.annotations.SerializedName +import com.navi.common.model.GenericWarningResponse +import com.navi.common.model.Money import com.navi.naviwidgets.models.response.ToastWidget import com.naviapp.personalloanrevamp.models.InfoBottomSheetConfig -import com.navi.common.model.Money -import com.navi.common.model.GenericWarningResponse data class WorkDetailsContent( @SerializedName("employmentType") val employmentType: String? = null, @@ -30,11 +30,13 @@ data class WorkDetailsContent( @SerializedName("shouldShowNewDesign") val shouldShowNewDesign: Boolean? = null, @SerializedName("monthlyInfo") val monthlyInfo: MonthlyInfo? = null, @SerializedName("incomeTooltip") val incomeTooltip: String? = null, - @SerializedName("employmentTypeBottomSheet") val employmentTypeBottomSheet: InfoBottomSheetConfig? = null, - @SerializedName("dataSafetyBottomSheet") val dataSafetyBottomSheet: InfoBottomSheetConfig? = null + @SerializedName("employmentTypeBottomSheet") + val employmentTypeBottomSheet: InfoBottomSheetConfig? = null, + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null ) data class MonthlyInfo( @SerializedName("title") val title: String? = null, @SerializedName("hint") val hint: String? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt b/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt index cdb587a84f..2650acee63 100644 --- a/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt @@ -27,6 +27,7 @@ import com.naviapp.home.model.WidgetResponse import com.naviapp.homeloandigital.common.models.CallAssistanceResponse import com.naviapp.homeloandigital.common.models.RequestCallbackRequest import com.naviapp.homeloandigital.common.models.RequestCallbackResponse +import com.naviapp.homeloandigital.landingpage.model.HLLandingPageResponse import com.naviapp.homeloandigital.models.* import com.naviapp.homeloandigital.models.HomeLoanSanctionLetterResponse import com.naviapp.homeloandigital.models.request.HomeLoanDocumentIdRequest @@ -35,6 +36,7 @@ import com.naviapp.homeloandigital.models.request.StatementUploadWebViewUrlReque import com.naviapp.homeloandigital.models.response.* import com.naviapp.models.* import com.naviapp.models.EmiDetail +import com.naviapp.models.RedirectPageStatus import com.naviapp.models.request.* import com.naviapp.models.response.* import com.naviapp.models.response.Details @@ -1119,6 +1121,9 @@ interface RetrofitService { @QueryMap queryMap: HashMap ): Response> + @GET("/home-loan/customers/me/journey/landing-page") + suspend fun fetchHomeLoanLandingPageResponse(): Response> + @PATCH("/home-loan/customers/me/journey/v1/form?action=CUSTOMIZE_LOAN") suspend fun submitCustomLoanDetails( @Body customLoanDetails: CustomLoanDetails, diff --git a/app/src/main/java/com/naviapp/network/util/Utils.kt b/app/src/main/java/com/naviapp/network/util/Utils.kt index cbe1239582..f0b5b8d7b5 100644 --- a/app/src/main/java/com/naviapp/network/util/Utils.kt +++ b/app/src/main/java/com/naviapp/network/util/Utils.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -24,19 +24,12 @@ import retrofit2.converter.gson.GsonConverterFactory fun createRetrofitClient(okttpClientBuilder: OkHttpClient.Builder): Retrofit { val percentDeserializer = - GsonBuilder().registerTypeAdapter( - WidgetConfig::class.java, - WidgetConfigDeserializer() - ).registerTypeAdapter( - NaviWidget::class.java, - NaviWidgetJsonDeserializer() - ).registerTypeAdapter( - NaviWidget::class.java, - NaviWidgetJsonDeserializer() - ).registerTypeAdapter( - ParameterValue::class.java, - ParameterValueJsonDeserializer() - ).create() + GsonBuilder() + .registerTypeAdapter(WidgetConfig::class.java, WidgetConfigDeserializer()) + .registerTypeAdapter(NaviWidget::class.java, NaviWidgetJsonDeserializer()) + .registerTypeAdapter(NaviWidget::class.java, NaviWidgetJsonDeserializer()) + .registerTypeAdapter(ParameterValue::class.java, ParameterValueJsonDeserializer()) + .create() return Retrofit.Builder() .baseUrl(BuildConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create(percentDeserializer)) @@ -53,7 +46,9 @@ fun getNetworkInfo(timeOutInSeconds: Long = ApiConstants.API_CONNECT_TIMEOUT_VAL ) } -fun getNetworkInfoSuperApp(timeOutInSeconds: Long = ApiConstants.API_CONNECT_TIMEOUT_VALUE): NetworkInfo { +fun getNetworkInfoSuperApp( + timeOutInSeconds: Long = ApiConstants.API_CONNECT_TIMEOUT_VALUE +): NetworkInfo { return NetworkInfo( appVersionName = BuildConfig.VERSION_NAME, appVersionCode = BuildConfig.VERSION_CODE.toString(), diff --git a/app/src/main/java/com/naviapp/part_prepayment/fragments/IncomeSourceBottomSheet.kt b/app/src/main/java/com/naviapp/part_prepayment/fragments/IncomeSourceBottomSheet.kt index 566b7e5898..8609d75865 100644 --- a/app/src/main/java/com/naviapp/part_prepayment/fragments/IncomeSourceBottomSheet.kt +++ b/app/src/main/java/com/naviapp/part_prepayment/fragments/IncomeSourceBottomSheet.kt @@ -61,9 +61,9 @@ class IncomeSourceBottomSheet : BaseBottomSheet(), RadioButtonListener { NaviAnalytics.naviAnalytics.sendGenericAnalyticsData( bottomSheetInfo?.footer?.primaryAction?.metaData?.clickedData, props = - mutableMapOf( - Pair(NaviAnalytics.SOURCE, selectedRelation?.title?.text.orEmpty()) - ) + mutableMapOf( + Pair(NaviAnalytics.SOURCE, selectedRelation?.title?.text.orEmpty()) + ) ) (parentFragment as? IncomeSourceSelectedListener)?.onIncomeSourceSelected(this) } @@ -101,4 +101,4 @@ interface IncomeSourceSelectedListener { fun onIncomeSourceSelected( bottomSheetInfoContent: com.navi.naviwidgets.models.BottomSheetInfoContent ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/payment/adapters/DisbursedTransactionsAdapter.kt b/app/src/main/java/com/naviapp/payment/adapters/DisbursedTransactionsAdapter.kt index 0ff94b0564..07f8d72aa0 100644 --- a/app/src/main/java/com/naviapp/payment/adapters/DisbursedTransactionsAdapter.kt +++ b/app/src/main/java/com/naviapp/payment/adapters/DisbursedTransactionsAdapter.kt @@ -1,25 +1,29 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.payment.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.naviapp.databinding.ItemDisbursedTransactionBinding -import com.naviapp.databinding.TransactionHistoryRowItemBinding import com.naviapp.payment.models.DisbursedTransaction import com.naviapp.payment.views.DisbursementTransactionView - class DisbursedTransactionsAdapter(private val disbursedTransactions: List) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionHistoryVH { - val binding = ItemDisbursedTransactionBinding.inflate(LayoutInflater.from(parent.context), parent, false) + val binding = + ItemDisbursedTransactionBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) return TransactionHistoryVH(binding.root as DisbursementTransactionView) } @@ -37,5 +41,4 @@ class DisbursedTransactionsAdapter(private val disbursedTransactions: List binding.tabLayoutGroup.isVisible = true binding.emiDisbursementsList.adapter = DisbursedTransactionsAdapter(transactions) - arguments?.getString(ARG_SELECT_EMI_DISBURSEMENT) - ?.takeIf { it == Constants.TRUE }?.let { - binding.emiDisbursements.performClick() - } + arguments + ?.getString(ARG_SELECT_EMI_DISBURSEMENT) + ?.takeIf { it == Constants.TRUE } + ?.let { binding.emiDisbursements.performClick() } } } } @@ -119,9 +119,7 @@ class TransactionHistoryFragment : BaseFragment() { } private fun initListeners() { - transactionHistoryVM.transactions.observeNonNull(this) { - updatePaymentTransactionsTab(it) - } + transactionHistoryVM.transactions.observeNonNull(this) { updatePaymentTransactionsTab(it) } } private fun updatePaymentTransactionsTab(transactionDetails: List?) { @@ -137,5 +135,4 @@ class TransactionHistoryFragment : BaseFragment() { override val screenName: String get() = "" - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/payment/models/DisbursedTransaction.kt b/app/src/main/java/com/naviapp/payment/models/DisbursedTransaction.kt index 057b06bad7..9ede92ec45 100644 --- a/app/src/main/java/com/naviapp/payment/models/DisbursedTransaction.kt +++ b/app/src/main/java/com/naviapp/payment/models/DisbursedTransaction.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.payment.models import com.google.gson.annotations.SerializedName @@ -5,29 +12,21 @@ import com.navi.naviwidgets.models.response.ImageFieldData import com.navi.naviwidgets.models.response.TextFieldData data class DisbursedTransactionsResponse( - @SerializedName("content") - val content: List? = null + @SerializedName("content") val content: List? = null ) data class DisbursedTransaction( - @SerializedName("header") - val header: Header? = null, - @SerializedName("items") - val transactionItems: List? = null + @SerializedName("header") val header: Header? = null, + @SerializedName("items") val transactionItems: List? = null ) data class Header( - @SerializedName("leftIcon") - val leftIcon: ImageFieldData? = null, - @SerializedName("title") - val title: TextFieldData? = null, - @SerializedName("backgroundColor") - val backgroundColor: String? = null + @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("backgroundColor") val backgroundColor: String? = null ) data class TransactionItem( - @SerializedName("leftText") - val leftText: TextFieldData? = null, - @SerializedName("rightText") - val rightText: TextFieldData? = null, -) \ No newline at end of file + @SerializedName("leftText") val leftText: TextFieldData? = null, + @SerializedName("rightText") val rightText: TextFieldData? = null, +) diff --git a/app/src/main/java/com/naviapp/payment/repositories/TransactionHistoryRepository.kt b/app/src/main/java/com/naviapp/payment/repositories/TransactionHistoryRepository.kt index 5633e1176b..0a186e078b 100644 --- a/app/src/main/java/com/naviapp/payment/repositories/TransactionHistoryRepository.kt +++ b/app/src/main/java/com/naviapp/payment/repositories/TransactionHistoryRepository.kt @@ -1,6 +1,7 @@ /* - * * - * * Copyright (c) 2020 . All rights reserved @Navi + * + * * Copyright © 2020-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -16,5 +17,4 @@ class TransactionHistoryRepository : ResponseCallback() { suspend fun fetchDisbursedTransactions(accountNumber: String) = apiResponseCallback(retrofitService().fetchDisbursedEmiTransactions(accountNumber)) - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/payment/viewmodel/TransactionHistoryVM.kt b/app/src/main/java/com/naviapp/payment/viewmodel/TransactionHistoryVM.kt index 4acb5bbadf..9d3464614f 100644 --- a/app/src/main/java/com/naviapp/payment/viewmodel/TransactionHistoryVM.kt +++ b/app/src/main/java/com/naviapp/payment/viewmodel/TransactionHistoryVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -9,12 +9,10 @@ package com.naviapp.payment.viewmodel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.navi.insurance.claim.view_claim.ClaimsListViewState import com.navi.common.viewmodel.BaseVM import com.naviapp.payment.models.DisbursedTransactionsResponse import com.naviapp.payment.models.TransactionDetail import com.naviapp.payment.repositories.TransactionHistoryRepository -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -44,7 +42,9 @@ class TransactionHistoryVM : BaseVM() { coroutineScope.launch { val response = repository.fetchDisbursedTransactions(accountNumber) if (response.error == null && response.errors.isNullOrEmpty()) { - _disbursedTransactionsState.emit(DisbursedTransactionsState.Success(response.data!!)) + _disbursedTransactionsState.emit( + DisbursedTransactionsState.Success(response.data!!) + ) } else { updateErrorMessage(response.error) } @@ -53,7 +53,8 @@ class TransactionHistoryVM : BaseVM() { } sealed class DisbursedTransactionsState { - class Success(val disbursementTransactionsResponse: DisbursedTransactionsResponse) : DisbursedTransactionsState() + class Success(val disbursementTransactionsResponse: DisbursedTransactionsResponse) : + DisbursedTransactionsState() object Failure : DisbursedTransactionsState() object Init : DisbursedTransactionsState() } diff --git a/app/src/main/java/com/naviapp/payment/views/DisbursementTransactionView.kt b/app/src/main/java/com/naviapp/payment/views/DisbursementTransactionView.kt index 5f84797bb4..8930081163 100644 --- a/app/src/main/java/com/naviapp/payment/views/DisbursementTransactionView.kt +++ b/app/src/main/java/com/naviapp/payment/views/DisbursementTransactionView.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.naviapp.payment.views import android.content.Context @@ -11,7 +12,6 @@ import android.graphics.Color import android.util.AttributeSet import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -28,12 +28,17 @@ import com.naviapp.databinding.LineItemDisbursedTransactionBinding import com.naviapp.payment.models.DisbursedTransaction import com.naviapp.payment.models.TransactionItem -class DisbursementTransactionView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null -) : CardView(context, attrs) { +class DisbursementTransactionView +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null) : CardView(context, attrs) { private val binding: DisbursementTransactionViewBinding = - DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.disbursement_transaction_view, this, true) + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.disbursement_transaction_view, + this, + true + ) init { radius = dpToPx(10) @@ -42,30 +47,33 @@ class DisbursementTransactionView @JvmOverloads constructor( } fun setProperties(disbursedTransaction: DisbursedTransaction) { - binding.headerContainer.isVisible = disbursedTransaction.header?.takeIf { it.title != null }?.let { header -> - binding.headerText.setTextFieldData(header.title) - header.backgroundColor?.takeIf { isValidHexColor(it) }?.let { - binding.headerContainer.setBackgroundColor(Color.parseColor(it)) - } - binding.headerIcon.isVisible = header.leftIcon.isNotNull() - if (header.leftIcon != null) { - Glide.with(context) - .load(NaviWidgetIconUtils.getImageFromIconCode(header.leftIcon.iconCode)) - .into(binding.headerIcon) - } - true - } ?: run { - false - } + binding.headerContainer.isVisible = + disbursedTransaction.header + ?.takeIf { it.title != null } + ?.let { header -> + binding.headerText.setTextFieldData(header.title) + header.backgroundColor + ?.takeIf { isValidHexColor(it) } + ?.let { binding.headerContainer.setBackgroundColor(Color.parseColor(it)) } + binding.headerIcon.isVisible = header.leftIcon.isNotNull() + if (header.leftIcon != null) { + Glide.with(context) + .load( + NaviWidgetIconUtils.getImageFromIconCode(header.leftIcon.iconCode) + ) + .into(binding.headerIcon) + } + true + } + ?: run { false } binding.itemsContainer.removeAllViews() disbursedTransaction.transactionItems?.forEach { binding.itemsContainer.addView(getItemView(it)) binding.itemsContainer.isVisible = true - } ?: run { - binding.itemsContainer.isVisible = false } + ?: run { binding.itemsContainer.isVisible = false } } private fun getItemView(transactionItem: TransactionItem): View { @@ -74,5 +82,4 @@ class DisbursementTransactionView @JvmOverloads constructor( binding.rightText.setTextFieldData(transactionItem.rightText) return binding.root } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/permission/adapters/PermissionAdapter.kt b/app/src/main/java/com/naviapp/permission/adapters/PermissionAdapter.kt index 871c00687d..2d5d5b1e24 100644 --- a/app/src/main/java/com/naviapp/permission/adapters/PermissionAdapter.kt +++ b/app/src/main/java/com/naviapp/permission/adapters/PermissionAdapter.kt @@ -18,10 +18,10 @@ import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView import com.navi.base.sharedpref.PreferenceManager +import com.navi.common.model.permission.PermissionTile import com.navi.common.utils.setShakeAnimation import com.naviapp.R import com.naviapp.databinding.PermissionTileLayoutBinding -import com.naviapp.permission.models.PermissionTile import com.naviapp.utils.PERMISSION_COLLAPSIBLE import com.naviapp.utils.isValidIndex diff --git a/app/src/main/java/com/naviapp/permission/utils/PermissionUtil.kt b/app/src/main/java/com/naviapp/permission/utils/PermissionUtil.kt index 0a1ec4fd2f..9dde5960b9 100644 --- a/app/src/main/java/com/naviapp/permission/utils/PermissionUtil.kt +++ b/app/src/main/java/com/naviapp/permission/utils/PermissionUtil.kt @@ -17,6 +17,7 @@ import android.provider.Settings import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import com.navi.common.managers.PermissionsManager +import com.navi.common.model.permission.PermissionTile import com.navi.common.utils.log import com.navi.insurance.util.FirebaseRemoteConfigUtils import com.naviapp.BuildConfig @@ -24,7 +25,6 @@ import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.app.NaviApplication import com.naviapp.permission.models.PermissionDeniedBinder -import com.naviapp.permission.models.PermissionTile import com.naviapp.utils.Constants import com.naviapp.utils.EMPTY import com.naviapp.utils.IconUtils diff --git a/app/src/main/java/com/naviapp/personalloan/factory/LoanDetailsV2VHFactoryImpl.kt b/app/src/main/java/com/naviapp/personalloan/factory/LoanDetailsV2VHFactoryImpl.kt index 986159bd30..56207ff746 100644 --- a/app/src/main/java/com/naviapp/personalloan/factory/LoanDetailsV2VHFactoryImpl.kt +++ b/app/src/main/java/com/naviapp/personalloan/factory/LoanDetailsV2VHFactoryImpl.kt @@ -9,11 +9,7 @@ package com.naviapp.personalloan.factory import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import com.google.gson.Gson -import com.navi.common.listeners.ClickableTextListener -import com.navi.common.model.ClickableTextType import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.interfaces.RewardsInfoWidgetInfo import com.navi.naviwidgets.widgets.RewardsInfoWidgetLayout @@ -31,7 +27,6 @@ import com.naviapp.personalloanrevamp.getloanRevamp.listeners.LoanDetailsV2Widge import com.naviapp.personalloanrevamp.getloanRevamp.listeners.RecyclerViewListener import com.naviapp.personalloanrevamp.models.* import com.naviapp.personalloanrevamp.models.response.SecurityTextWithIconWidgetConfig -import com.naviapp.utils.BindingAdapterUtil.setStyledText class LoanDetailsV2VHFactoryImpl : VHFactory() { diff --git a/app/src/main/java/com/naviapp/personalloan/factory/VHFactory.kt b/app/src/main/java/com/naviapp/personalloan/factory/VHFactory.kt index 6cbf1d9a03..8f84a97f5b 100644 --- a/app/src/main/java/com/naviapp/personalloan/factory/VHFactory.kt +++ b/app/src/main/java/com/naviapp/personalloan/factory/VHFactory.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloan.factory /* * @@ -8,9 +15,7 @@ package com.naviapp.personalloan.factory import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import androidx.viewbinding.ViewBinding import com.navi.naviwidgets.callbacks.WidgetCallback -import com.navi.naviwidgets.databinding.LayoutRewardsInfoBinding import com.naviapp.models.response.AdditionalData import com.naviapp.models.response.WidgetConfig import com.naviapp.personalloanrevamp.getloanRevamp.listeners.RecyclerViewListener @@ -28,4 +33,4 @@ abstract class VHFactory { additionalData: AdditionalData? = null, callback: WidgetCallback? = null, ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/activities/BankAccountVerificationLoaderActivity.kt b/app/src/main/java/com/naviapp/personalloan/getloan/activities/BankAccountVerificationLoaderActivity.kt index 2d6f5420e0..7153a13e96 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/activities/BankAccountVerificationLoaderActivity.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/activities/BankAccountVerificationLoaderActivity.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -19,10 +19,10 @@ import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent +import com.navi.base.sharedpref.PreferenceManager import com.navi.common.firebasedb.* import com.navi.common.model.ModuleNameV2 import com.navi.common.model.UploadDataAsyncResponse -import com.navi.base.sharedpref.PreferenceManager import com.navi.common.ui.activity.BaseActivity import com.navi.common.utils.* import com.naviapp.R @@ -32,23 +32,21 @@ import com.naviapp.common.customview.CircularProgressBar import com.naviapp.common.navigator.ScreenNavigator import com.naviapp.databinding.BankAccountVerificationLoaderActivityBinding import com.naviapp.errors.activities.ErrorActivity +import com.naviapp.manager.UserManager import com.naviapp.models.request.BankDetail import com.naviapp.models.response.PennyDropBankData import com.naviapp.personalloan.getloan.bankdetails.fragments.BankDetailsFragment.Companion.PENNY_DROP_BANK_DATA -import com.naviapp.manager.UserManager import com.naviapp.personalloan.getloan.bankdetails.models.BankLoanStatusType import com.naviapp.personalloan.getloan.bankdetails.viewmodels.BankDetailsVM import com.naviapp.utils.Constants import com.naviapp.utils.LOAN_APPLICATION_ID import com.naviapp.utils.orValue -class BankAccountVerificationLoaderActivity : BaseActivity(), - CircularProgressBar.ProgressCompletedListener, View.OnClickListener { +class BankAccountVerificationLoaderActivity : + BaseActivity(), CircularProgressBar.ProgressCompletedListener, View.OnClickListener { private lateinit var binding: BankAccountVerificationLoaderActivityBinding - private val viewModel by lazy { - ViewModelProvider(this).get(BankDetailsVM::class.java) - } + private val viewModel by lazy { ViewModelProvider(this).get(BankDetailsVM::class.java) } private var timer: CountDownTimer? = null private var apiPollScheduler: ApiPollScheduler? = null private var firebaseDataReceiveListener: FirebaseDataReceiveListener? = null @@ -124,8 +122,7 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), binding.loader.setBackgroundImage(ContextCompat.getDrawable(this, R.drawable.ic_error_svg)) binding.loader.setColor(R.color.red) binding.statusTv.text = getString(R.string.failed) - binding.statusDetailsTv.text = - getString(R.string.enter_correct_bank_details) + binding.statusDetailsTv.text = getString(R.string.enter_correct_bank_details) binding.actionBtn.setProperties(getString(R.string.edit_bank_details)) binding.actionBtn.visibility = View.VISIBLE binding.noteTv.visibility = View.GONE @@ -169,56 +166,60 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), apiPollInit(it) } } - } ?: run { - setUpRetryBankAccountVerificationScreen() } + ?: run { setUpRetryBankAccountVerificationScreen() } } } private fun navigateToPennyDropFailure() { - Handler().postDelayed({ - if (isDestroyed) return@postDelayed - NaviTrackEvent.setStartTs(screenName) - val resultIntent = Intent() - resultIntent.putExtra(PENNY_DROP_FAILURE, true) - val pennyDropBankData = PennyDropBankData( - bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), - bankIfscName = intent.getStringExtra(Constants.BANK_IFSC), - bankAccountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), - loanApplicationId = intent.getStringExtra(Constants.LOAN_APPLICATION_ID) + Handler() + .postDelayed( + { + if (isDestroyed) return@postDelayed + NaviTrackEvent.setStartTs(screenName) + val resultIntent = Intent() + resultIntent.putExtra(PENNY_DROP_FAILURE, true) + val pennyDropBankData = + PennyDropBankData( + bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), + bankIfscName = intent.getStringExtra(Constants.BANK_IFSC), + bankAccountNumber = + intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), + loanApplicationId = intent.getStringExtra(Constants.LOAN_APPLICATION_ID) + ) + resultIntent.putExtras( + Bundle().apply { putParcelable(PENNY_DROP_BANK_DATA, pennyDropBankData) } + ) + setResult(Activity.RESULT_OK, resultIntent) + finish() + }, + NEXT_SCREEN_TRANSITION_DELAY ) - resultIntent.putExtras(Bundle().apply { - putParcelable(PENNY_DROP_BANK_DATA, pennyDropBankData) - }) - setResult(Activity.RESULT_OK, resultIntent) - finish() - }, NEXT_SCREEN_TRANSITION_DELAY) } private fun submitBankDetails() { val loanType = intent.getStringExtra(Constants.LOAN_TYPE) ?: Constants.TYPE_PERSONAL_LOAN - val bankDetail = BankDetail( - beneficiaryName = UserManager.getName(), - accountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), - ifscCode = intent.getStringExtra(Constants.BANK_IFSC), - bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), - type = if (loanType == Constants.TYPE_HOME_LOAN) Constants.ENACH else BankLoanStatusType.DISBURSEMENT - ) - val loanApplicationId = intent.getStringExtra(Constants.PERSONAL_LOAN_APPLICATION_ID) - ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) + val bankDetail = + BankDetail( + beneficiaryName = UserManager.getName(), + accountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), + ifscCode = intent.getStringExtra(Constants.BANK_IFSC), + bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), + type = + if (loanType == Constants.TYPE_HOME_LOAN) Constants.ENACH + else BankLoanStatusType.DISBURSEMENT + ) + val loanApplicationId = + intent.getStringExtra(Constants.PERSONAL_LOAN_APPLICATION_ID) + ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) - - loanApplicationId?.let { - viewModel.addBankDetail(bankDetail, it, loanType) - } + loanApplicationId?.let { viewModel.addBankDetail(bankDetail, it, loanType) } } private fun observeBankAccountDetailData() { viewModel.asyncDataResponse.observeNullable(this) { data -> - data?.status?.let { - onGetAddBankResponse(it) - } + data?.status?.let { onGetAddBankResponse(it) } } } @@ -237,14 +238,10 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), binding.goBackBtn.visibility = View.INVISIBLE binding.actionBtn.visibility = View.INVISIBLE binding.statusTv.text = getString(R.string.please_wait) - binding.statusDetailsTv.text = - getString(R.string.penny_drop) + binding.statusDetailsTv.text = getString(R.string.penny_drop) binding.loader.setColor(R.color.colorDeepBlueGray) binding.loader.setBackgroundImage( - ContextCompat.getDrawable( - this, - R.drawable.ic_bank_icon_svg - ) + ContextCompat.getDrawable(this, R.drawable.ic_bank_icon_svg) ) binding.loader.setDivisionDurations(1000, 2000, 4000, 8000, 16000, 32000) binding.loader.run() @@ -253,29 +250,27 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), } private fun initFirebase(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onGetAddBankResponse(it.status) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { onGetAddBankResponse(it.status) } } } - } firebaseDataHelper?.clear() firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - ADD_BANK_ACCOUNT, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + ADD_BANK_ACCOUNT, + requestId, + notificationPath + ) + } } - private fun onGetAddBankResponse( - status: String? - ) { + private fun onGetAddBankResponse(status: String?) { if (TextUtils.equals(status, FirebaseStatusType.SUCCESS)) { apiPollScheduler?.stopApiPoll() deInitializeAsyncListeners() @@ -285,7 +280,9 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), apiPollScheduler?.stopApiPoll() deInitializeAsyncListeners() cancelTimer() - viewModel.bankDetailAdd.value?.requestId?.let { viewModel.fetchAsyncRequestWithError(it) } + viewModel.bankDetailAdd.value?.requestId?.let { + viewModel.fetchAsyncRequestWithError(it) + } if (intent.getBooleanExtra(GetLoanActivity.IS_FOR_SECOND_LOAN_JOURNEY, false)) { viewModel.fetchRejectionDetails() } else viewModel.checkUiStatus() @@ -300,10 +297,10 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), private fun apiPollInit(uploadDataAsyncResponse: UploadDataAsyncResponse) { apiPollScheduler = ApiPollScheduler( - numberOfRetry = uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue( - NUMBER_OF_RETRY - ), - doOnTimeout = { runOnUiThread { handleTimeOutError() } }) { + numberOfRetry = + uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue(NUMBER_OF_RETRY), + doOnTimeout = { runOnUiThread { handleTimeOutError() } } + ) { viewModel.fetchAsyncRequestData(uploadDataAsyncResponse.requestId.orEmpty()) } apiPollScheduler?.scheduleApiPoll() @@ -319,8 +316,7 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), binding.loader.setColor(R.color.green) binding.loader.setBackgroundImage(null) binding.statusTv.text = getString(R.string.success) - binding.statusDetailsTv.text = - getString(R.string.your_bank_account_is_verified) + binding.statusDetailsTv.text = getString(R.string.your_bank_account_is_verified) binding.statusTv.visibility = View.GONE binding.noteTv.visibility = View.GONE loadTimeEventTracker.onLoadingCompleted(NaviAnalytics.PL_PENNY_DROP_LOAD_TIME) @@ -335,13 +331,17 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), } private fun navigateToNextScreen() { - Handler().postDelayed({ - if (isDestroyed) return@postDelayed - NaviTrackEvent.setStartTs(screenName) - val intent = Intent() - setResult(Activity.RESULT_OK, intent) - finish() - }, NEXT_SCREEN_TRANSITION_DELAY) + Handler() + .postDelayed( + { + if (isDestroyed) return@postDelayed + NaviTrackEvent.setStartTs(screenName) + val intent = Intent() + setResult(Activity.RESULT_OK, intent) + finish() + }, + NEXT_SCREEN_TRANSITION_DELAY + ) } override fun onClick(view: View?) { @@ -366,18 +366,15 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), private fun startCountDownTimer(timeInMilliSec: Long) { if (timer == null) { - timer = object : CountDownTimer( - timeInMilliSec, - Constants.MILLISECONDS_PER_SECOND.toLong() - ) { - override fun onTick(millisUntilFinished: Long) { + timer = + object : + CountDownTimer(timeInMilliSec, Constants.MILLISECONDS_PER_SECOND.toLong()) { + override fun onTick(millisUntilFinished: Long) {} + override fun onFinish() { + setUpBankVerificationPendingStatus() + } } - - override fun onFinish() { - setUpBankVerificationPendingStatus() - } - } } timer?.start() } @@ -411,8 +408,7 @@ class BankAccountVerificationLoaderActivity : BaseActivity(), const val PENNY_DROP_FAILURE = "PENNY_DROP_FAILURE" private const val BANK_VERIFICATION_SUCCESS = "BANK_VERIFICATION_SUCCESS" private const val GET_LOAN_VIEW_ANIMATION_DELAY = 1000L - private const val NEXT_SCREEN_TRANSITION_DELAY = - GET_LOAN_VIEW_ANIMATION_DELAY + 100L + private const val NEXT_SCREEN_TRANSITION_DELAY = GET_LOAN_VIEW_ANIMATION_DELAY + 100L private const val NUMBER_OF_RETRY = 24 } } diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/activities/GetLoanActivity.kt b/app/src/main/java/com/naviapp/personalloan/getloan/activities/GetLoanActivity.kt index 8425111abf..20cd229c37 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/activities/GetLoanActivity.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/activities/GetLoanActivity.kt @@ -95,15 +95,22 @@ import com.naviapp.utils.OFFER_ID import com.razorpay.PaymentData import com.razorpay.PaymentResultWithDataListener import dagger.hilt.android.AndroidEntryPoint -import org.json.JSONObject import java.util.* +import org.json.JSONObject @AndroidEntryPoint -class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClickListener, - SelfieCaptureListener, PaymentResultWithDataListener, +class GetLoanActivity : + BaseActivity(), + FragmentInteractionListener, + View.OnClickListener, + SelfieCaptureListener, + PaymentResultWithDataListener, EnachListener, - AadhaarVerificationListener, OKYCListener, LoanDetailsFragment.UpdateUiListener, - HeaderInteractionListener, DigioResponseListener { + AadhaarVerificationListener, + OKYCListener, + LoanDetailsFragment.UpdateUiListener, + HeaderInteractionListener, + DigioResponseListener { private lateinit var binding: ActivityGetLoanBinding private var disbursementDetailsData: DisbursementDetailsResponse? = null @@ -120,15 +127,11 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic private val configurationVM by lazy { ViewModelProvider(this).get(ConfigVM::class.java) } private val inAppUpdateVM by lazy { ViewModelProvider(this).get(InAppUpdateVM::class.java) } private val loanDetailsAndEmiSharedVM by lazy { - ViewModelProvider(this).get( - LoanDetailsAndEmiSharedVM::class.java - ) + ViewModelProvider(this).get(LoanDetailsAndEmiSharedVM::class.java) } - private val neoEyedVM: NeoEyedVM by - lazy { ViewModelProvider(this).get(NeoEyedVM::class.java) } + private val neoEyedVM: NeoEyedVM by lazy { ViewModelProvider(this).get(NeoEyedVM::class.java) } private val loadTimeEventTracker = LoadTimeEventTracker() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) selfieVerificationHelper = SelfieVerificationHelper() @@ -184,8 +187,7 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic private fun getIntentData() { isSecondLoanJourney = intent?.getBooleanExtra(IS_FOR_SECOND_LOAN_JOURNEY, false).orFalse() - loanViewHelper = - GetLoanViewHelper(isSecondLoanJourney) + loanViewHelper = GetLoanViewHelper(isSecondLoanJourney) } override fun onRequestPermissionsResult( @@ -195,18 +197,18 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (!isValidRequestCode(requestCode) || permissions.isEmpty()) return - kycSharedVM.permissionResult.value = - Triple(permissions, grantResults, requestCode) + kycSharedVM.permissionResult.value = Triple(permissions, grantResults, requestCode) } - private fun isValidRequestCode(requestCode: Int) = requestCode in listOf( - SELFIE_REQUEST_CODE, - PAN_CAMERA_REQUEST_CODE, - UPLOAD_AADHAR_REQUEST_CODE, - VIDEO_KYC_REQUEST_CODE, - AADHAR_OTP_REQUEST_CODE - ) - + private fun isValidRequestCode(requestCode: Int) = + requestCode in + listOf( + SELFIE_REQUEST_CODE, + PAN_CAMERA_REQUEST_CODE, + UPLOAD_AADHAR_REQUEST_CODE, + VIDEO_KYC_REQUEST_CODE, + AADHAR_OTP_REQUEST_CODE + ) private fun handleIntentData() { val bundle = intent.extras ?: Bundle() @@ -216,11 +218,12 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic } private fun initializeData(savedInstanceState: Bundle?) { - disbursementDetailsData = if (savedInstanceState == null) { - intent.getParcelableExtra(DISBURSEMENT_DETAILS) - } else { - savedInstanceState.getParcelable(DISBURSEMENT_DETAILS) - } + disbursementDetailsData = + if (savedInstanceState == null) { + intent.getParcelableExtra(DISBURSEMENT_DETAILS) + } else { + savedInstanceState.getParcelable(DISBURSEMENT_DETAILS) + } } override fun onSaveInstanceState(outState: Bundle) { @@ -240,24 +243,18 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic override fun navigateTo(screen: String, bundle: Bundle?) { deInitSharedObservers() bundle?.let { - it.putBoolean( - IS_FOR_SECOND_LOAN_JOURNEY, isSecondLoanJourney - ) + it.putBoolean(IS_FOR_SECOND_LOAN_JOURNEY, isSecondLoanJourney) it.putString(OFFER_ID, intent?.getStringExtra(OFFER_ID)) } if (isDead()) return val tag = loanViewHelper?.getTag(screen) val fragment = - supportFragmentManager.findFragmentByTag(tag) ?: loanViewHelper?.getFragment( - screen, - bundle - ) + supportFragmentManager.findFragmentByTag(tag) + ?: loanViewHelper?.getFragment(screen, bundle) fragment?.let { f -> if (bundle == null) { val newBundle = Bundle() - newBundle.putBoolean( - IS_FOR_SECOND_LOAN_JOURNEY, isSecondLoanJourney - ) + newBundle.putBoolean(IS_FOR_SECOND_LOAN_JOURNEY, isSecondLoanJourney) f.arguments = newBundle } else f.arguments = bundle val fragmentTransaction = supportFragmentManager.beginTransaction() @@ -268,7 +265,8 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic commitAllowingStateLoss() } } - } ?: run { NaviDeepLinkNavigator.navigate(this, CtaData(url = screen), true) } + } + ?: run { NaviDeepLinkNavigator.navigate(this, CtaData(url = screen), true) } } private fun updateCurrentScreen(screen: String) { @@ -296,16 +294,14 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic QUESTIONNAIRE_SCREEN -> currentScreen = NaviAnalytics.QUESTIONNAIRE_SCREEN ADDRESS_VERIFICATION_SCREEN -> currentScreen = NaviAnalytics.KYC_ADDRESS ADDRESS_VERIFICATION_PROOF_SCREEN -> currentScreen = NaviAnalytics.KYC_ADDRESS_PROOF - ADDRESS_PHYSICAL_VERIFICATION -> currentScreen = - NaviAnalytics.KYC_PHYSICAL_ADDR_VERIFICATION_SCREEN - EMI_DATE_CHANGE_SCREEN -> currentScreen = - NaviAnalytics.EMI_DATE_CHANGE - UPDATED_EMI_CALENDAR -> currentScreen = - NaviAnalytics.EMI_UPDATED_CALENDAR + ADDRESS_PHYSICAL_VERIFICATION -> + currentScreen = NaviAnalytics.KYC_PHYSICAL_ADDR_VERIFICATION_SCREEN + EMI_DATE_CHANGE_SCREEN -> currentScreen = NaviAnalytics.EMI_DATE_CHANGE + UPDATED_EMI_CALENDAR -> currentScreen = NaviAnalytics.EMI_UPDATED_CALENDAR MFI_CONSENT_SCREEN -> currentScreen = NaviAnalytics.MFI_CONSENT_SCREEN EMI_SELECTOR_SCREEN -> currentScreen = NaviAnalytics.EMI_SELECTOR_SCREEN - EFFECTIVE_INTEREST_COST_SCREEN -> currentScreen = - NaviAnalytics.EFFECTIVE_INTEREST_COST_SCREEN + EFFECTIVE_INTEREST_COST_SCREEN -> + currentScreen = NaviAnalytics.EFFECTIVE_INTEREST_COST_SCREEN } } @@ -366,10 +362,7 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic ApiConstants.API_SUCCESS_CODE, SUCCESS, SUCCESS, - AadhaarDetails( - data?.getString("share_code"), - data?.getString("encoded_zip") - ) + AadhaarDetails(data?.getString("share_code"), data?.getString("encoded_zip")) ) ) NaviAnalytics.naviAnalytics.Kyc().onDigioKycSuccess() @@ -417,21 +410,19 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic ) ) } - - } ?: run { - kycSharedVM.setUserHasCancelled(false) - kycSharedVM.setAadhaarVerificationData( - AadhaarVerificationData( - ApiConstants.API_SUCCESS_CODE, - SUCCESS, - SUCCESS, - AadhaarDetails( - txnId = data?.optString("txnId") + } + ?: run { + kycSharedVM.setUserHasCancelled(false) + kycSharedVM.setAadhaarVerificationData( + AadhaarVerificationData( + ApiConstants.API_SUCCESS_CODE, + SUCCESS, + SUCCESS, + AadhaarDetails(txnId = data?.optString("txnId")) ) ) - ) - NaviAnalytics.naviAnalytics.Kyc().onDigiTapKycSuccess() - } + NaviAnalytics.naviAnalytics.Kyc().onDigiTapKycSuccess() + } } @Suppress("unused") @@ -480,17 +471,23 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic } override fun onMandateStart(data: EnachMandateDetailsResponse, provider: String) { - if (System.currentTimeMillis() - apiCallLastTime <= Constants.API_CALL_MULTI_CLICK_THRESOLD_DUR) return - if (data.mandateId?.isNotBlank() - .orFalse() && data.metadata?.razorpayCustomerId?.isNotBlank().orFalse() + if ( + System.currentTimeMillis() - apiCallLastTime <= + Constants.API_CALL_MULTI_CLICK_THRESOLD_DUR + ) + return + if ( + data.mandateId?.isNotBlank().orFalse() && + data.metadata?.razorpayCustomerId?.isNotBlank().orFalse() ) { when (provider) { ProviderType.RAZORPAY -> { - val requestData = EnachRequest( - orderId = data.mandateId, - customerId = data.metadata?.razorpayCustomerId, - recurring = "1" // default value for razorpay emandate - ) + val requestData = + EnachRequest( + orderId = data.mandateId, + customerId = data.metadata?.razorpayCustomerId, + recurring = "1" // default value for razorpay emandate + ) onStartPayment(requestData, data.metadata?.accountKey.orEmpty()) } } @@ -511,7 +508,6 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic } } - override fun onPaymentError(code: Int, description: String?, data: PaymentData?) { setEnachStatusCompeteData(description, data, code) enachSharedVM.setEnachResponse(data?.orderId, FAILURE) @@ -539,16 +535,11 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic status = if (code == null) SUCCESS else FAILURE ) ) - } catch (e: Exception) { - - } + } catch (e: Exception) {} } override fun onStartVerification(data: AadhaarDetailsResponse) { - aadhaarVerificationHelper?.init( - this, - data - ) + aadhaarVerificationHelper?.init(this, data) } override fun changeHeaderBackGround(blackOut: Boolean) { @@ -562,9 +553,8 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic if (resultCode == Activity.RESULT_OK) loanDetailsAndEmiSharedVM.setCouponOfferId( CouponInfo( - data?.getStringExtra( - IntentConstants.KEY_COUPON_OFFER_ID - ), PromoOfferAction.APPLY + data?.getStringExtra(IntentConstants.KEY_COUPON_OFFER_ID), + PromoOfferAction.APPLY ) ) } @@ -638,7 +628,8 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic override fun getCurrentFragmentScreenName(): String { return try { - (supportFragmentManager.findFragmentById(R.id.get_loan_container) as? BaseFragment)?.screenName + (supportFragmentManager.findFragmentById(R.id.get_loan_container) as? BaseFragment) + ?.screenName ?: screenName } catch (e: Exception) { screenName @@ -656,10 +647,8 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic private fun enableUxCamRecording(uxcamKey: String, journey: String) { if (configurationVM.shouldEnableUxCamRecording(journey)) { UxcamUtil.instance.init( - uxcamKey, mapOf( - Pair("screenName", screenName), - Pair("journey", journey) - ) + uxcamKey, + mapOf(Pair("screenName", screenName), Pair("journey", journey)) ) val externalUserId = PreferenceManager.getStringPreference(CommonPrefConstants.USER_EXTERNAL_ID) @@ -675,19 +664,16 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic fun updateApp( screenName: String, - showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? = null + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? = null ) { when (screenName) { - com.navi.common.utils.Constants.HOME_LOAN -> if (com.navi.common.utils.Constants.SHOWN_APP_UPDATE_IN_HOME) { - return - } else { - com.navi.common.utils.Constants.SHOWN_APP_UPDATE_IN_HOME = true - } - com.navi.common.utils.Constants.KYC -> { - } + com.navi.common.utils.Constants.HOME_LOAN -> + if (com.navi.common.utils.Constants.SHOWN_APP_UPDATE_IN_HOME) { + return + } else { + com.navi.common.utils.Constants.SHOWN_APP_UPDATE_IN_HOME = true + } + com.navi.common.utils.Constants.KYC -> {} } inAppUpdate.checkForUpdate(screenName, ::updateCallback, showDialog) { _, _ -> } } @@ -695,10 +681,7 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic private fun updateCallback( screenName: String, isAppUpdateAvailable: Boolean, - showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? = null + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? = null ) { if (isAppUpdateAvailable) { inAppUpdateVM.inAppUpdate.observeNonNull(this) { inAppUpdateResponse -> @@ -712,4 +695,4 @@ class GetLoanActivity : BaseActivity(), FragmentInteractionListener, View.OnClic } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/activities/LoanDisbursementLoaderActivity.kt b/app/src/main/java/com/naviapp/personalloan/getloan/activities/LoanDisbursementLoaderActivity.kt index 19f4a9f4ca..f6782deae0 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/activities/LoanDisbursementLoaderActivity.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/activities/LoanDisbursementLoaderActivity.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -15,6 +15,7 @@ import android.text.TextUtils import android.view.View import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat +import androidx.core.util.Pair as UtilPair import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent @@ -51,14 +52,11 @@ import com.naviapp.utils.Constants.PREVIOUS_SCREEN import com.naviapp.utils.LOAN_APPLICATION_ID import com.naviapp.utils.orZero import kotlin.Pair -import androidx.core.util.Pair as UtilPair -class LoanDisbursementLoaderActivity : BaseActivity(), - CircularProgressBar.ProgressCompletedListener, RewardsOverlayDismiss { +class LoanDisbursementLoaderActivity : + BaseActivity(), CircularProgressBar.ProgressCompletedListener, RewardsOverlayDismiss { private lateinit var binding: LoanDisbursementLoaderActivityBinding - private val viewModel by lazy { - ViewModelProvider(this).get(LoanDisbursementVM::class.java) - } + private val viewModel by lazy { ViewModelProvider(this).get(LoanDisbursementVM::class.java) } private var timer: CountDownTimer? = null private var apiPollScheduler: ApiPollScheduler? = null private var firebaseDataHelper: FirebaseDataHelper? = null @@ -68,8 +66,7 @@ class LoanDisbursementLoaderActivity : BaseActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = - DataBindingUtil.setContentView(this, R.layout.loan_disbursement_loader_activity) + binding = DataBindingUtil.setContentView(this, R.layout.loan_disbursement_loader_activity) super.setContentView(binding.root) NaviTrackEvent.sendScreenTransitionEvent(screenName) initError() @@ -92,13 +89,11 @@ class LoanDisbursementLoaderActivity : BaseActivity(), ) } - private val handleFetchBasicDetailsRetry: View.OnClickListener = View.OnClickListener { _ -> - viewModel.fetchLoanBasicDetails() - } + private val handleFetchBasicDetailsRetry: View.OnClickListener = + View.OnClickListener { _ -> viewModel.fetchLoanBasicDetails() } - private val handleGetDisbursementStatusRetry: View.OnClickListener = View.OnClickListener { _ -> - fetchDisbursementStatus() - } + private val handleGetDisbursementStatusRetry: View.OnClickListener = + View.OnClickListener { _ -> fetchDisbursementStatus() } private fun initObservers() { observeLoanBasicDetails() @@ -190,9 +185,8 @@ class LoanDisbursementLoaderActivity : BaseActivity(), data.details?.message ?: getString(R.string.sending_amount) initFirebase(it, data.notificationPath.orEmpty()) apiPollInit(it) - } ?: run { - handleTimeOutError() } + ?: run { handleTimeOutError() } } } @@ -233,25 +227,23 @@ class LoanDisbursementLoaderActivity : BaseActivity(), viewModel.dataAsyncResponse.value?.details?.netDisbursalAmount.orZero() ) navigateNextScreen(screenName = REWARDS_DELIGHT_SCREEN, bundle = bundle) - } ?: kotlin.run { - navigateToNextScreen() } + ?: kotlin.run { navigateToNextScreen() } } - viewModel.rewardsError.observeNonNull(this) { - navigateToNextScreen() - } + viewModel.rewardsError.observeNonNull(this) { navigateToNextScreen() } } private fun initFirebase(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onGetDisbursementStatusResponse(it.status, null, null, null, false) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { + onGetDisbursementStatusResponse(it.status, null, null, null, false) + } } } - } firebaseDataHelper = FirebaseDataHelper() firebaseDataHelper?.initFirebaseDataReceiver( lifecycle, @@ -276,20 +268,18 @@ class LoanDisbursementLoaderActivity : BaseActivity(), private fun startCountDownTimer(timeInMilliSec: Long) { if (timer == null) { - timer = object : CountDownTimer( - timeInMilliSec, - Constants.MILLISECONDS_PER_SECOND.toLong() - ) { - override fun onTick(millisUntilFinished: Long) { + timer = + object : + CountDownTimer(timeInMilliSec, Constants.MILLISECONDS_PER_SECOND.toLong()) { + override fun onTick(millisUntilFinished: Long) {} + override fun onFinish() { + setUpLoanDisbursementFailureScreen( + viewModel.loanDisbursementResponse.value?.details?.delayedMessage, + null + ) + } } - - override fun onFinish() { - setUpLoanDisbursementFailureScreen( - viewModel.loanDisbursementResponse.value?.details?.delayedMessage, null - ) - } - } } timer?.start() } @@ -298,7 +288,8 @@ class LoanDisbursementLoaderActivity : BaseActivity(), apiPollScheduler = ApiPollScheduler( numberOfRetry = NUMBER_OF_RETRY, - doOnTimeout = { runOnUiThread { handleTimeOutError() } }) { + doOnTimeout = { runOnUiThread { handleTimeOutError() } } + ) { viewModel.fetchAsyncRequestData(requestId) } apiPollScheduler?.scheduleApiPoll() @@ -352,22 +343,24 @@ class LoanDisbursementLoaderActivity : BaseActivity(), } private fun getTransitionsPairAsBundle(): Bundle? { - val circularProgressTransition = UtilPair.create( - binding.loader, - getString(R.string.circular_progress_bar_transition) - ) - val statusTransition = UtilPair.create( - binding.statusTv, - getString(R.string.status_transition) - ) - val statusDetailTransition = UtilPair.create( - binding.statusDetailsTv, - getString(R.string.status_detail_transition) - ) - val options = ActivityOptionsCompat.makeSceneTransitionAnimation( - this, - circularProgressTransition, statusTransition - ) + val circularProgressTransition = + UtilPair.create( + binding.loader, + getString(R.string.circular_progress_bar_transition) + ) + val statusTransition = + UtilPair.create(binding.statusTv, getString(R.string.status_transition)) + val statusDetailTransition = + UtilPair.create( + binding.statusDetailsTv, + getString(R.string.status_detail_transition) + ) + val options = + ActivityOptionsCompat.makeSceneTransitionAnimation( + this, + circularProgressTransition, + statusTransition + ) return options.toBundle() } @@ -383,38 +376,42 @@ class LoanDisbursementLoaderActivity : BaseActivity(), screenName = it, bundle = bundle ) - } ?: kotlin.run { - viewModel.abSettings.value?.result?.let { result -> - navigateNextScreen( - screenName = if (result) { - CROSS_SELL_SCREEN - } else { - LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN - }, - bundle = Bundle() - ) - } ?: kotlin.run { - navigateNextScreen( - screenName = LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN, - bundle = Bundle() - ) - } } + ?: kotlin.run { + viewModel.abSettings.value?.result?.let { result -> + navigateNextScreen( + screenName = + if (result) { + CROSS_SELL_SCREEN + } else { + LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN + }, + bundle = Bundle() + ) + } + ?: kotlin.run { + navigateNextScreen( + screenName = LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN, + bundle = Bundle() + ) + } + } } private fun navigateNextScreen(screenName: String, bundle: Bundle) { - Handler(Looper.getMainLooper()).postDelayed( - { - if (isDead()) return@postDelayed - bundle.putParcelable(PREVIOUS_SCREEN, PreviousScreenNameRequest(DISBURSED)) - ScreenNavigator.instance.startActivityWithNoActivityStack( - this, - screenName, - bundle - ) - }, - NEXT_SCREEN_TRANSITION_DELAY - ) + Handler(Looper.getMainLooper()) + .postDelayed( + { + if (isDead()) return@postDelayed + bundle.putParcelable(PREVIOUS_SCREEN, PreviousScreenNameRequest(DISBURSED)) + ScreenNavigator.instance.startActivityWithNoActivityStack( + this, + screenName, + bundle + ) + }, + NEXT_SCREEN_TRANSITION_DELAY + ) } override fun onRewardsOverlayDismiss() { @@ -433,4 +430,4 @@ class LoanDisbursementLoaderActivity : BaseActivity(), private const val NEXT_SCREEN_TRANSITION_DELAY = 1000L private const val NUMBER_OF_RETRY = 12 } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/BankDetailsFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/BankDetailsFragment.kt index e59cf1a0bb..1fe0bc1af9 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/BankDetailsFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/BankDetailsFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -69,8 +69,13 @@ import com.naviapp.utils.Constants.ZERO import com.naviapp.utils.orZero import kotlinx.android.synthetic.main.view_common_footer.view.* -class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListener, - View.OnKeyListener, View.OnFocusChangeListener, OnSelectBankListener, +class BankDetailsFragment : + BaseFragment(), + View.OnClickListener, + FindIfscListener, + View.OnKeyListener, + View.OnFocusChangeListener, + OnSelectBankListener, FooterInteractionListener { private lateinit var binding: BankDetailsFragmentBinding private val viewModel by lazy { ViewModelProvider(this).get(BankDetailsVM::class.java) } @@ -89,8 +94,9 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - loanApplicationId = arguments?.getString(Constants.PERSONAL_LOAN_APPLICATION_ID) - ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) + loanApplicationId = + arguments?.getString(Constants.PERSONAL_LOAN_APPLICATION_ID) + ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) loanAccountNumber = arguments?.getString(Constants.LOAN_ACCOUNT_NUMBER) loanType = arguments?.getString(LOAN_TYPE) ?: Constants.TYPE_PERSONAL_LOAN journeyType = arguments?.getString(JOURNEY_TYPE) @@ -116,9 +122,7 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen arguments?.getParcelable(KEY_CTA)?.let { it.parameters?.let { parameters -> parameters.forEach { item -> - item.key?.let { key -> - ctaQueryMap[key] = "${item.value}" - } + item.key?.let { key -> ctaQueryMap[key] = "${item.value}" } } } } @@ -136,22 +140,24 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen ) } - private val handleFetchBanksError = View.OnClickListener { - showLoader() - viewModel.fetchAllBanks() - } + private val handleFetchBanksError = + View.OnClickListener { + showLoader() + viewModel.fetchAllBanks() + } - private val handleFetchDisbursementDetailsError = View.OnClickListener { - showLoader() - val id = loanApplicationId - if (!id.isNullOrEmpty()) - viewModel.fetchDisbursementDetails(id, ctaQueryMap) - } + private val handleFetchDisbursementDetailsError = + View.OnClickListener { + showLoader() + val id = loanApplicationId + if (!id.isNullOrEmpty()) viewModel.fetchDisbursementDetails(id, ctaQueryMap) + } - private val handleFetchLoanBasicDetailsError = View.OnClickListener { - showLoader() - viewModel.fetchLoanBasicDetails() - } + private val handleFetchLoanBasicDetailsError = + View.OnClickListener { + showLoader() + viewModel.fetchLoanBasicDetails() + } private fun initUi() { naviAnalyticsEventTracker.onPageLands(loanApplicationId, loanType, journeyType) @@ -162,12 +168,13 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen } else { binding.footerView.divider.isVisible = false binding.accountHolderName.verificationBanner.rootItem.isVisible = false - val isForSecondLoanJourney = - arguments?.getBoolean(IS_FOR_SECOND_LOAN_JOURNEY).orFalse() + val isForSecondLoanJourney = arguments?.getBoolean(IS_FOR_SECOND_LOAN_JOURNEY).orFalse() binding.bankDisclaimerView.bankDisclaimerCv.visibility = if (isForSecondLoanJourney) View.GONE else View.VISIBLE - UxcamUtil.instance.occludeSensitiveView(binding.bankAccountNumberLayout.bankAccountNumber) + UxcamUtil.instance.occludeSensitiveView( + binding.bankAccountNumberLayout.bankAccountNumber + ) arguments?.getBoolean(EDIT_ACCOUNT)?.let { if (it) { disbursalData?.disbursementDetails?.let { disbursementDetails -> @@ -177,7 +184,8 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen setDefaultHeader(disbursalData?.header) setDefaultFooter(disbursalData?.footer) } else initData() - } ?: run { initData() } + } + ?: run { initData() } binding.ifscLayout.ifscEt.filters += InputFilter.AllCaps() binding.ifscLayout.ifscEt.setOnKeyListener(this) binding.footerView.changeNextButtonBackground(false) @@ -187,25 +195,14 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen private fun setFullScreenErrorData(fullScreenErrorInfo: FullScreenErrorInfo) { binding.fullScreenErrorLayout.visibility = View.VISIBLE headerInteractionListener?.hideHeader() - fullScreenErrorInfo.iconCode?.run { - IconUtils.updateIcon( - this, binding.errorImage - ) - } ?: kotlin.run { - binding.errorImage.visibility = View.GONE - } + fullScreenErrorInfo.iconCode?.run { IconUtils.updateIcon(this, binding.errorImage) } + ?: kotlin.run { binding.errorImage.visibility = View.GONE } - fullScreenErrorInfo.title?.run { - binding.errorTitleTv.text = this - } ?: kotlin.run { - binding.errorTitleTv.visibility = View.GONE - } + fullScreenErrorInfo.title?.run { binding.errorTitleTv.text = this } + ?: kotlin.run { binding.errorTitleTv.visibility = View.GONE } - fullScreenErrorInfo.subTitle?.run { - binding.errorSubtitleTv.text = this - } ?: kotlin.run { - binding.errorSubtitleTv.visibility = View.GONE - } + fullScreenErrorInfo.subTitle?.run { binding.errorSubtitleTv.text = this } + ?: kotlin.run { binding.errorSubtitleTv.visibility = View.GONE } fullScreenErrorInfo.cta?.run { binding.goBackBtn.setProperties( @@ -218,9 +215,8 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen headerInteractionListener?.onBackPressed() } } - } ?: kotlin.run { - binding.goBackBtn.visibility = View.GONE } + ?: kotlin.run { binding.goBackBtn.visibility = View.GONE } } private fun checkForPrevIFSCHint() { @@ -269,7 +265,9 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen private fun initListeners() { binding.ifscLayout.findIfscTv.setOnClickListener(this) - binding.bankAccountNumberLayout.bankAccountNumberEt.setDependentFormTextView(binding.bankAccountNumberLayout.bankAccountNumberTv) + binding.bankAccountNumberLayout.bankAccountNumberEt.setDependentFormTextView( + binding.bankAccountNumberLayout.bankAccountNumberTv + ) binding.bankNameLayout.bankActv.setDependentTextView(binding.bankNameLayout.bankNameTv) binding.bankNameLayout.bankActv.setOnClickListener(this) binding.accountHolderName.verificationBanner.actionTv.setOnClickListener(this) @@ -284,8 +282,7 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen start: Int, count: Int, after: Int - ) { - } + ) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { if (s?.length == IFSC_CODE_LENGTH) { @@ -294,16 +291,18 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen } } - override fun afterTextChanged(s: Editable?) { - } - }) + override fun afterTextChanged(s: Editable?) {} + } + ) binding.ifscLayout.ifscEt.setDependentFormTextView(binding.ifscLayout.ifscTv) binding.ifscLayout.branchNameTv.setOnClickListener(this) binding.bankAccountNumberLayout.bankAccountNumberEt.onFocusChangeListener = this binding.ifscLayout.ifscEt.onFocusChangeListener = this binding.bankNameLayout.bankActv.onFocusChangeListener = this binding.accountHolderName.checkboxCb.setOnClickListener { - naviAnalyticsEventTracker.onCheckBoxClicked(binding.accountHolderName.checkboxCb.isChecked) + naviAnalyticsEventTracker.onCheckBoxClicked( + binding.accountHolderName.checkboxCb.isChecked + ) enableConfirmIfRequired() } binding.accountHolderName.pennyAttemptsLayout.subtitleTv.setOnClickListener(this) @@ -339,20 +338,17 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen listener?.navigateTo( GetLoanActivity.BANK_DETAILS_AUTO_DEBIT_SCREEN, Bundle().apply { - putParcelable( - DISBURSEMENT_DETAILS, - disbursementDetailsResponse - ) - putString( - PERSONAL_LOAN_APPLICATION_ID, - loanApplicationId - ) - }) + putParcelable(DISBURSEMENT_DETAILS, disbursementDetailsResponse) + putString(PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) + } + ) return@observeNonNull } } else -> { - binding.bankAccountNumberLayout.bankAccountNumberEt.setText(it.bankDetails?.accountNumber) + binding.bankAccountNumberLayout.bankAccountNumberEt.setText( + it.bankDetails?.accountNumber + ) binding.ifscLayout.ifscEt.setText(it.bankDetails?.ifscCode) binding.bankNameLayout.bankActv.setText(it.bankDetails?.bankName) } @@ -396,36 +392,29 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen binding.bankDisclaimerView.bankDisclaimerCv.isVisible = false } - disbursalData.headerTitle?.let { - binding.bankDetailsTv.text = disbursalData.headerTitle - } ?: run { - binding.bankDetailsTv.isVisible = false - } + disbursalData.headerTitle?.let { binding.bankDetailsTv.text = disbursalData.headerTitle } + ?: run { binding.bankDetailsTv.isVisible = false } binding.accountHolderName.titleTv.text = disbursalData.accountHolderDeclaration binding.accountHolderName.checkboxCb.isChecked = disbursalData.isAccountHolderDeclarationSet.orFalse() enableConfirmIfRequired() - disbursalData.pennyDropFailureData?.bottomOverlay?.let { - binding.overlayBinder = it - } + disbursalData.pennyDropFailureData?.bottomOverlay?.let { binding.overlayBinder = it } disbursalData.verifiedBannerData?.let { bannerData -> binding.accountHolderName.verificationBanner.rootItem.toggleAnimatedVisibility( - isVisible = true, translateY = true + isVisible = true, + translateY = true ) with(binding.accountHolderName.verificationBanner) { verifiedTitle.text = bannerData.title - bannerData.iconCode?.let { - IconUtils.updateIcon(it, titleImg) - } + bannerData.iconCode?.let { IconUtils.updateIcon(it, titleImg) } bannerData.cta?.let { actionTv.text = it.title actionTv.setOnClickListener { makeFieldsEditable() - binding.accountHolderName.verificationBanner.rootItem.toggleAnimatedVisibility( - isVisible = false, translateY = true - ) + binding.accountHolderName.verificationBanner.rootItem + .toggleAnimatedVisibility(isVisible = false, translateY = true) } } } @@ -509,58 +498,54 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen binding.bankAccountNumberLayout.bankAccountNumberEt.text binding.ifscLayout.showIfscTv.text = binding.ifscLayout.ifscEt.text - Handler().postDelayed( - { - val bankDetails = BankDetail( - bankName = binding.bankNameLayout.showBankNameTv.text.toString(), - accountNumber = binding.bankAccountNumberLayout.showBankAccountNumberTv.text.toString(), - ifscCode = binding.ifscLayout.ifscEt.text.toString() - ) - viewModel.disbursementDetails.value?.disbursementDetails?.bankDetails = bankDetails - if (arguments?.getString(ARG_SOURCE) == SOURCE_CHANGE_BANK_ACCOUNT) { - listener?.navigateTo( - LoanApplicationDetailActivity.BANK_AUTO_DEBIT_SCREEN, - Bundle().apply { - putParcelable( - DISBURSEMENT_DETAILS, - arguments?.getParcelable( - DISBURSEMENT_DETAILS + Handler() + .postDelayed( + { + val bankDetails = + BankDetail( + bankName = binding.bankNameLayout.showBankNameTv.text.toString(), + accountNumber = + binding.bankAccountNumberLayout.showBankAccountNumberTv.text + .toString(), + ifscCode = binding.ifscLayout.ifscEt.text.toString() + ) + viewModel.disbursementDetails.value?.disbursementDetails?.bankDetails = + bankDetails + if (arguments?.getString(ARG_SOURCE) == SOURCE_CHANGE_BANK_ACCOUNT) { + listener?.navigateTo( + LoanApplicationDetailActivity.BANK_AUTO_DEBIT_SCREEN, + Bundle().apply { + putParcelable( + DISBURSEMENT_DETAILS, + arguments?.getParcelable( + DISBURSEMENT_DETAILS + ) ) - ) - putString( - Constants.LOAN_APPLICATION_ID, - loanApplicationId - ) - putString( - Constants.LOAN_ACCOUNT_NUMBER, - loanAccountNumber - ) - putBoolean( - Constants.MANDATE_CHANGE, - true - ) - putString( - SUB_REDIRECT, - RE_ENACH - ) - }) - } else { - listener?.navigateTo( - viewModel.disbursementDetails.value?.footer?.nextCta?.url - ?: GetLoanActivity.BANK_DETAILS_AUTO_DEBIT_SCREEN, Bundle().apply { - putParcelable( - DISBURSEMENT_DETAILS, - viewModel.disbursementDetails.value - ) - putString(Constants.PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) - putString(SUB_REDIRECT, arguments?.getString(SUB_REDIRECT)) - putParcelable(KEY_CTA, arguments?.getParcelable(KEY_CTA)) - }) - } - }, - if (arguments?.getString(ARG_SOURCE) == SOURCE_CHANGE_BANK_ACCOUNT) 0 else AUTO_DEBIT_PAGE_DELAY - ) - + putString(Constants.LOAN_APPLICATION_ID, loanApplicationId) + putString(Constants.LOAN_ACCOUNT_NUMBER, loanAccountNumber) + putBoolean(Constants.MANDATE_CHANGE, true) + putString(SUB_REDIRECT, RE_ENACH) + } + ) + } else { + listener?.navigateTo( + viewModel.disbursementDetails.value?.footer?.nextCta?.url + ?: GetLoanActivity.BANK_DETAILS_AUTO_DEBIT_SCREEN, + Bundle().apply { + putParcelable( + DISBURSEMENT_DETAILS, + viewModel.disbursementDetails.value + ) + putString(Constants.PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) + putString(SUB_REDIRECT, arguments?.getString(SUB_REDIRECT)) + putParcelable(KEY_CTA, arguments?.getParcelable(KEY_CTA)) + } + ) + } + }, + if (arguments?.getString(ARG_SOURCE) == SOURCE_CHANGE_BANK_ACCOUNT) 0 + else AUTO_DEBIT_PAGE_DELAY + ) } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { @@ -568,19 +553,22 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen when (requestCode) { PENNY_DROP_REQUEST -> { if (resultCode == Activity.RESULT_OK) { - if (intent?.getBooleanExtra( - BankAccountVerificationLoaderActivity.PENNY_DROP_FAILURE, - false - ).orFalse() + if ( + intent + ?.getBooleanExtra( + BankAccountVerificationLoaderActivity.PENNY_DROP_FAILURE, + false + ) + .orFalse() ) { - intent?.extras?.getParcelable(PENNY_DROP_BANK_DATA) - ?.let { - viewModel.setPennyDropBankData(it) - } + intent + ?.extras + ?.getParcelable(PENNY_DROP_BANK_DATA) + ?.let { viewModel.setPennyDropBankData(it) } onPennyDropFailure() } else { - binding.accountHolderName.pennyAttemptsLayout.pennyDropAttemptsCl.visibility = - View.GONE + binding.accountHolderName.pennyAttemptsLayout.pennyDropAttemptsCl + .visibility = View.GONE onPennyDropSuccess() } } @@ -604,19 +592,15 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen journeyType ) val intent = Intent(activity, BankAccountVerificationLoaderActivity::class.java) - intent.putExtra( - BANK_NAME_SELECTED, - binding.bankNameLayout.bankActv.text.toString() - ) + intent.putExtra(BANK_NAME_SELECTED, binding.bankNameLayout.bankActv.text.toString()) intent.putExtra( BANK_ACCOUNT_NUMBER, binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString() ) intent.putExtra(BANK_IFSC, binding.ifscLayout.ifscEt.text.toString()) intent.putExtra( - IS_FOR_SECOND_LOAN_JOURNEY, arguments?.getBoolean( - IS_FOR_SECOND_LOAN_JOURNEY, false - ) + IS_FOR_SECOND_LOAN_JOURNEY, + arguments?.getBoolean(IS_FOR_SECOND_LOAN_JOURNEY, false) ) intent.putExtra(PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) intent.putExtra(LOAN_TYPE, loanType) @@ -631,14 +615,19 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen binding.bankNameLayout.bankActv.setError(getString(R.string.enter_a_valid_bank_name)) validated = false } - if (binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().isBlank() || - binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().length < MIN_BANK_ACCOUNT_NUMBER_LENGTH + if ( + binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().isBlank() || + binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().length < + MIN_BANK_ACCOUNT_NUMBER_LENGTH ) { - binding.bankAccountNumberLayout.bankAccountNumberEt.setError(getString(R.string.enter_a_valid_account_number)) + binding.bankAccountNumberLayout.bankAccountNumberEt.setError( + getString(R.string.enter_a_valid_account_number) + ) validated = false } - if (binding.ifscLayout.ifscEt.text.toString().isBlank() || - binding.ifscLayout.ifscEt.text.toString().length != IFSC_CODE_LENGTH + if ( + binding.ifscLayout.ifscEt.text.toString().isBlank() || + binding.ifscLayout.ifscEt.text.toString().length != IFSC_CODE_LENGTH ) { binding.ifscLayout.ifscEt.setError(getString(R.string.enter_eleven_digit_code_message)) validated = false @@ -647,8 +636,11 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen validated = false } - if ((binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString() == _bankDetails?.accountNumber) - && (binding.ifscLayout.ifscEt.text.toString() == _bankDetails?.ifscCode && _bankDetails?.duplicateError.isNotNull()) + if ( + (binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString() == + _bankDetails?.accountNumber) && + (binding.ifscLayout.ifscEt.text.toString() == _bankDetails?.ifscCode && + _bankDetails?.duplicateError.isNotNull()) ) { _bankDetails?.duplicateError?.run { binding.bankAccountNumberLayout.accountErrorTv.text = this @@ -660,10 +652,11 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen } private fun enableConfirmIfRequired() { - if (binding.bankNameLayout.bankActv.text.isNotBlank() && - binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().isNotBlank() && - binding.ifscLayout.ifscEt.text.toString().isNotBlank() && - binding.accountHolderName.checkboxCb.isChecked + if ( + binding.bankNameLayout.bankActv.text.isNotBlank() && + binding.bankAccountNumberLayout.bankAccountNumberEt.text.toString().isNotBlank() && + binding.ifscLayout.ifscEt.text.toString().isNotBlank() && + binding.accountHolderName.checkboxCb.isChecked ) { binding.footerView.changeNextButtonBackground(true) } else { @@ -673,21 +666,18 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen private fun openFindIfsc() { naviAnalyticsEventTracker.onFindIfscTap(loanType, journeyType) - bankNamesWithCodes.firstOrNull { - it.name == binding.bankNameLayout.bankActv.text.toString() - }?.let { - val findIfscFragment = IfscFragment.newInstance(it.code, it.name) - findIfscFragment.setListener(this) - safelyShowBottomSheet(findIfscFragment, IfscFragment.TAG) - } ?: run { - context?.toast(R.string.select_valid_bank) - } + bankNamesWithCodes + .firstOrNull { it.name == binding.bankNameLayout.bankActv.text.toString() } + ?.let { + val findIfscFragment = IfscFragment.newInstance(it.code, it.name) + findIfscFragment.setListener(this) + safelyShowBottomSheet(findIfscFragment, IfscFragment.TAG) + } + ?: run { context?.toast(R.string.select_valid_bank) } } private fun onChangeBankClicked() { - viewModel.disbursementDetails.value?.disbursementDetails?.let { - setDisbursalUiData(it) - } + viewModel.disbursementDetails.value?.disbursementDetails?.let { setDisbursalUiData(it) } } override fun onClick(view: View?) { @@ -696,9 +686,14 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen R.id.branch_name_tv -> openFindIfsc() R.id.bank_actv -> openSelectBank() R.id.action_tv -> onChangeBankClicked() - R.id.subtitle_tv -> openPennyDropFailureBottomSheet( - viewModel.disbursementDetails.value?.disbursementDetails?.pennyDropFailureData?.bottomOverlay?.additionalData - ) + R.id.subtitle_tv -> + openPennyDropFailureBottomSheet( + viewModel.disbursementDetails.value + ?.disbursementDetails + ?.pennyDropFailureData + ?.bottomOverlay + ?.additionalData + ) } } @@ -714,10 +709,7 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen safelyShowBottomSheet(bankDetailFragment, SelectBankFragment.TAG) } - override fun onBranchSelected( - branchName: String?, - ifscCode: String? - ) { + override fun onBranchSelected(branchName: String?, ifscCode: String?) { val ifscFragment = childFragmentManager.findFragmentByTag(FindIfscFragment.TAG) as? IfscFragment ifscFragment?.safelyDismissDialog() @@ -741,14 +733,10 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen override fun onFocusChange(view: View?, hasFocus: Boolean) { when (view?.id) { - R.id.bank_account_number_et -> if (hasFocus) naviAnalyticsEventTracker.onAccountNumberEdit( - loanType, - journeyType - ) - R.id.ifsc_et -> if (hasFocus) naviAnalyticsEventTracker.onIfscEdit( - loanType, - journeyType - ) + R.id.bank_account_number_et -> + if (hasFocus) naviAnalyticsEventTracker.onAccountNumberEdit(loanType, journeyType) + R.id.ifsc_et -> + if (hasFocus) naviAnalyticsEventTracker.onIfscEdit(loanType, journeyType) R.id.bank_actv -> if (hasFocus) naviAnalyticsEventTracker.onBankNameSelected() } } @@ -774,8 +762,7 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen binding.ifscLayout.ifscEt.setText(bank.code + ZERO) binding.ifscLayout.branchNameTv.visibility = View.GONE binding.ifscLayout.findIfscTv.visibility = - if (!binding.bankNameLayout.bankActv.text.isBlank()) View.VISIBLE - else View.GONE + if (!binding.bankNameLayout.bankActv.text.isBlank()) View.VISIBLE else View.GONE } override fun onClickUnserviceableBank() { @@ -786,11 +773,11 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen ) } - override fun onFooterBackPress(ctaData: CtaData?) { ctaData?.url?.let { listener?.navigateTo( - it, Bundle().apply { + it, + Bundle().apply { putString(Constants.PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) } ) @@ -799,10 +786,18 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen override fun onFooterNextPress(ctaData: CtaData?, skipValidation: Boolean?) { val remainCount = - viewModel.disbursementDetails.value?.disbursementDetails?.pennyDropFailureData?.bottomOverlay?.remainingCount + viewModel.disbursementDetails.value + ?.disbursementDetails + ?.pennyDropFailureData + ?.bottomOverlay + ?.remainingCount if (remainCount.orZero() == 1) { openPennyDropFailureBottomSheet( - viewModel.disbursementDetails.value?.disbursementDetails?.pennyDropFailureData?.bottomOverlay?.lastAttemptBottomSheet + viewModel.disbursementDetails.value + ?.disbursementDetails + ?.pennyDropFailureData + ?.bottomOverlay + ?.lastAttemptBottomSheet ) } else { submitBankDetails() @@ -830,9 +825,7 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen const val EDIT_ACCOUNT = "EDIT_ACCOUNT" fun newInstance(bundle: Bundle?): BankDetailsFragment { - return BankDetailsFragment().apply { - arguments = bundle - } + return BankDetailsFragment().apply { arguments = bundle } } } @@ -846,23 +839,16 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen if (eventRequired) { val eventName = - if (loanType == Constants.TYPE_HOME_LOAN) NaviAnalytics.HL_PennyDropError_Popup else NaviAnalytics.PL_PennyDropError_Popup - sendPennyDropPopupEvent( - eventName, - pennyErrorBottomSheetData.title, - journeyType - ) + if (loanType == Constants.TYPE_HOME_LOAN) + NaviAnalytics.HL_PennyDropError_Popup + else NaviAnalytics.PL_PennyDropError_Popup + sendPennyDropPopupEvent(eventName, pennyErrorBottomSheetData.title, journeyType) } pennyDropFailureBottomSheet = PennyDropFailureBottomSheet.getInstance(pennyErrorBottomSheetData) pennyDropFailureBottomSheet?.let { - safelyShowBottomSheet( - it, - PennyDropFailureBottomSheet.TAG - ) - it.ctaData.observeNullable( - viewLifecycleOwner - ) { cta -> + safelyShowBottomSheet(it, PennyDropFailureBottomSheet.TAG) + it.ctaData.observeNullable(viewLifecycleOwner) { cta -> pennyDropFailureBottomSheet = null when (cta?.url) { PENNY_DROP_ATTEMPT -> submitBankDetails() @@ -886,10 +872,8 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen private fun getEventNameForPennyDrop(title: String?, loanType: String?): String? { val eventHeader = - if (loanType == Constants.TYPE_HOME_LOAN) - NaviAnalytics.HL_PennyDropError_Popup_Click - else - NaviAnalytics.PL_PennyDropError_Popup_Click + if (loanType == Constants.TYPE_HOME_LOAN) NaviAnalytics.HL_PennyDropError_Popup_Click + else NaviAnalytics.PL_PennyDropError_Popup_Click title?.let { val titleEvent = it.removeSpaces() return eventHeader.plus(titleEvent) @@ -901,7 +885,11 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen naviAnalyticsEventTracker.onPennyDropErrorEvent( eventName, viewModel.getPennyDropBankData()?.bankName, - viewModel.disbursementDetails.value?.disbursementDetails?.pennyDropFailureData?.bottomOverlay?.remainingCount, + viewModel.disbursementDetails.value + ?.disbursementDetails + ?.pennyDropFailureData + ?.bottomOverlay + ?.remainingCount, title, journey ) @@ -917,19 +905,12 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen journeyType ) val intent = Intent(activity, BankAccountVerificationLoaderActivity::class.java) - intent.putExtra( - BANK_NAME_SELECTED, - it.bankName - ) - intent.putExtra( - BANK_ACCOUNT_NUMBER, - it.bankAccountNumber - ) + intent.putExtra(BANK_NAME_SELECTED, it.bankName) + intent.putExtra(BANK_ACCOUNT_NUMBER, it.bankAccountNumber) intent.putExtra(BANK_IFSC, it.bankIfscName) intent.putExtra( - IS_FOR_SECOND_LOAN_JOURNEY, arguments?.getBoolean( - IS_FOR_SECOND_LOAN_JOURNEY, false - ) + IS_FOR_SECOND_LOAN_JOURNEY, + arguments?.getBoolean(IS_FOR_SECOND_LOAN_JOURNEY, false) ) intent.putExtra(PERSONAL_LOAN_APPLICATION_ID, it.loanApplicationId) intent.putExtra(LOAN_TYPE, loanType) @@ -937,4 +918,4 @@ class BankDetailsFragment : BaseFragment(), View.OnClickListener, FindIfscListen startActivityForResult(intent, PENNY_DROP_REQUEST) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/accountaggregator/AccountAggregatorFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/accountaggregator/AccountAggregatorFragment.kt index 18f938e411..69b3beccbd 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/accountaggregator/AccountAggregatorFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/fragments/accountaggregator/AccountAggregatorFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -23,29 +23,29 @@ import com.google.android.gms.auth.api.phone.SmsRetriever import com.google.android.gms.common.api.CommonStatusCodes import com.google.android.gms.common.api.Status import com.navi.analytics.utils.NaviTrackEvent -import com.navi.common.firebasedb.* -import com.navi.common.firebasedb.FirebaseStatusType import com.navi.base.model.CtaData import com.navi.base.sharedpref.PreferenceManager import com.navi.base.utils.BaseUtils +import com.navi.common.firebasedb.* +import com.navi.common.firebasedb.FirebaseStatusType +import com.navi.common.listeners.FragmentInterchangeListener +import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.* import com.navi.insurance.models.request.FlagUpdateRequest import com.navi.insurance.util.observeNullable import com.navi.naviwidgets.utils.FORWARD_SLASH import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.ui.fragment.BaseFragment import com.naviapp.common.fragment.CommonBottomSheet import com.naviapp.common.listeners.BackListener import com.naviapp.common.listeners.BottomSheetListener import com.naviapp.common.listeners.FooterInteractionListener -import com.navi.common.listeners.HeaderInteractionListener import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.common.navigator.NaviDeepLinkNavigator.INTERMEDIATE -import com.naviapp.dashboard.listeners.FragmentInteractionListener -import com.navi.common.listeners.FragmentInterchangeListener import com.naviapp.common.navigator.NaviDeepLinkNavigator.INTERMEDIATE_V2 import com.naviapp.common.navigator.NaviDeepLinkNavigator.LOAN_APPLICATION_V2 +import com.naviapp.dashboard.listeners.FragmentInteractionListener import com.naviapp.databinding.AccountAggregatorLayoutBinding import com.naviapp.errors.activities.ErrorActivity import com.naviapp.manager.UserManager @@ -78,20 +78,18 @@ import com.onemoney.custom.models.output.AuthSessionParams import com.onemoney.custom.models.output.ConsentDetailsResponse import com.onemoney.custom.models.output.FipList import com.onemoney.custom.models.output.LoginOtpResponse -import timber.log.Timber import java.util.regex.Pattern +import timber.log.Timber -class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, BackListener, - BottomSheetListener { +class AccountAggregatorFragment : + BaseFragment(), FooterInteractionListener, BackListener, BottomSheetListener { private var listener: FragmentInteractionListener? = null private var loanApplicationId: String? = null private var fipId: String? = null private var bankName: String? = null private lateinit var binding: AccountAggregatorLayoutBinding private val sharedVM: AggregatorSharedVM by lazy { - ViewModelProvider(this).get( - AggregatorSharedVM::class.java - ) + ViewModelProvider(this).get(AggregatorSharedVM::class.java) } private var apiPollScheduler: ApiPollScheduler? = null private var firebaseDataHelper: FirebaseDataHelper? = null @@ -105,80 +103,90 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac private var isOnConsentScreen: Boolean = false private val SMS_CONSENT_REQUEST = 2 - private val smsVerificationReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - try { - if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { - val extras = intent.extras - val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status - when (smsRetrieverStatus.statusCode) { - CommonStatusCodes.SUCCESS -> { - val consentIntent = - extras?.getParcelable(SmsRetriever.EXTRA_CONSENT_INTENT) - try { - startActivityForResult(consentIntent, SMS_CONSENT_REQUEST) - } catch (e: Exception) { - e.log() + private val smsVerificationReceiver = + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + try { + if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { + val extras = intent.extras + val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status + when (smsRetrieverStatus.statusCode) { + CommonStatusCodes.SUCCESS -> { + val consentIntent = + extras?.getParcelable(SmsRetriever.EXTRA_CONSENT_INTENT) + try { + startActivityForResult(consentIntent, SMS_CONSENT_REQUEST) + } catch (e: Exception) { + e.log() + } + } + CommonStatusCodes.TIMEOUT -> { + // Time out occurred, handle the error. } } - CommonStatusCodes.TIMEOUT -> { - // Time out occurred, handle the error. - } } + } catch (ex: Exception) { + ex.log() } - } catch (ex: Exception) { - ex.log() } } - } - private val bankOtpClickListener: View.OnClickListener = View.OnClickListener { - NaviTrackEvent.setStartTs(screenName) - sendOtpToLinkAccount() - } - - private val submitConsentClickListener: View.OnClickListener = View.OnClickListener { - NaviTrackEvent.setStartTs(screenName) - showLoader() - approveConsent() - } - - private val genericOnClickListener: View.OnClickListener = View.OnClickListener { - NaviTrackEvent.setStartTs(screenName) - onBackPressed() - } - - private val rejectConsentClickListener: View.OnClickListener = View.OnClickListener { - NaviTrackEvent.setStartTs(screenName) - var nextCta = INTERMEDIATE.plus(DIVIDER).plus(BANK_STATEMENT_VERIFICATION) - if (arguments?.getBoolean(IS_REVAMP_FLOW, false) == true) { - nextCta = INTERMEDIATE_V2.plus(DIVIDER) - .plus(IntermediateV2Helper.BANK_STATEMENT_VERIFICATION_V2) + private val bankOtpClickListener: View.OnClickListener = + View.OnClickListener { + NaviTrackEvent.setStartTs(screenName) + sendOtpToLinkAccount() } - val commonBottomSheet = CommonBottomSheet.newInstance( - screenName = NaviAnalytics.REJECT_CONSENT_REQUEST_BOTTOM_SHEET, - title = getString(R.string.reject_consent_request), - description = getString(R.string.reject_consent_message), - ctaData = CtaData( - title = getString(R.string.reject_consent_cta_title), - url = nextCta - ), - ctaDataOptional = CtaData(title = getString(R.string.no)) - ) - safelyShowBottomSheet(commonBottomSheet, CommonBottomSheet.TAG) - } - private val changeBankClickListener: View.OnClickListener = View.OnClickListener { - fragmentInterchangeListener?.navigateToNextScreen( - SubPageStatusType.BANK_STATEMENT_VERIFICATION, - Bundle() - ) - } + private val submitConsentClickListener: View.OnClickListener = + View.OnClickListener { + NaviTrackEvent.setStartTs(screenName) + showLoader() + approveConsent() + } + + private val genericOnClickListener: View.OnClickListener = + View.OnClickListener { + NaviTrackEvent.setStartTs(screenName) + onBackPressed() + } + + private val rejectConsentClickListener: View.OnClickListener = + View.OnClickListener { + NaviTrackEvent.setStartTs(screenName) + var nextCta = INTERMEDIATE.plus(DIVIDER).plus(BANK_STATEMENT_VERIFICATION) + if (arguments?.getBoolean(IS_REVAMP_FLOW, false) == true) { + nextCta = + INTERMEDIATE_V2.plus(DIVIDER) + .plus(IntermediateV2Helper.BANK_STATEMENT_VERIFICATION_V2) + } + val commonBottomSheet = + CommonBottomSheet.newInstance( + screenName = NaviAnalytics.REJECT_CONSENT_REQUEST_BOTTOM_SHEET, + title = getString(R.string.reject_consent_request), + description = getString(R.string.reject_consent_message), + ctaData = + CtaData( + title = getString(R.string.reject_consent_cta_title), + url = nextCta + ), + ctaDataOptional = CtaData(title = getString(R.string.no)) + ) + safelyShowBottomSheet(commonBottomSheet, CommonBottomSheet.TAG) + } + + private val changeBankClickListener: View.OnClickListener = + View.OnClickListener { + fragmentInterchangeListener?.navigateToNextScreen( + SubPageStatusType.BANK_STATEMENT_VERIFICATION, + Bundle() + ) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - loanApplicationId = arguments?.getString(Constants.PERSONAL_LOAN_APPLICATION_ID) - ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) + loanApplicationId = + arguments?.getString(Constants.PERSONAL_LOAN_APPLICATION_ID) + ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) fipId = arguments?.getString(FIP_ID) ?: "" bankName = arguments?.getString(BANK_NAME) ?: fipId } @@ -189,7 +197,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac try { activity?.registerReceiver(smsVerificationReceiver, intentFilter) } catch (exception: Exception) { - //receiver already registered + // receiver already registered } } @@ -216,8 +224,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } catch (e: Exception) { e.log() } - if (binding.otpView.isVisible) - binding.otpView.setOTP(code.orEmpty()) + if (binding.otpView.isVisible) binding.otpView.setOTP(code.orEmpty()) } override fun onCreateView( @@ -258,10 +265,8 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } private fun initUi() { - binding.titleTv.text = resources.getString( - R.string.discovered_accounts, - UserManager.getPhoneNumber() - ) + binding.titleTv.text = + resources.getString(R.string.discovered_accounts, UserManager.getPhoneNumber()) binding.titleTv.visibility = View.VISIBLE if (bankName.isNullOrEmpty()) { binding.bankInfoItem.root.visibility = View.GONE @@ -280,32 +285,34 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac private fun initOneMoneySdk(sessionId: String?) { val config = sharedVM.oneMoneyProviderConfig.value?.oneMoneyData if (!sessionId.isNullOrEmpty()) { - onemoney = context?.let { - config?.let { onemoneyConfig -> - Onemoney.init( - it, - onemoneyConfig.orgId ?: "", - onemoneyConfig.clientId ?: "", - onemoneyConfig.clientSecret ?: "", - onemoneyConfig.baseUrl ?: "", - sessionId - ) + onemoney = + context?.let { + config?.let { onemoneyConfig -> + Onemoney.init( + it, + onemoneyConfig.orgId ?: "", + onemoneyConfig.clientId ?: "", + onemoneyConfig.clientSecret ?: "", + onemoneyConfig.baseUrl ?: "", + sessionId + ) + } } - } initiateAccountSearch() preProcessFipData() } else { - onemoney = context?.let { - config?.let { onemoneyConfig -> - Onemoney.init( - it, - onemoneyConfig.orgId ?: "", - onemoneyConfig.clientId ?: "", - onemoneyConfig.clientSecret ?: "", - onemoneyConfig.baseUrl ?: "", - ) + onemoney = + context?.let { + config?.let { onemoneyConfig -> + Onemoney.init( + it, + onemoneyConfig.orgId ?: "", + onemoneyConfig.clientId ?: "", + onemoneyConfig.clientSecret ?: "", + onemoneyConfig.baseUrl ?: "", + ) + } } - } } } @@ -320,9 +327,8 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac discoverAccounts() } }, - onFailure = { - discoverAccounts() - }) + onFailure = { discoverAccounts() } + ) } private fun discoverAccounts() { @@ -334,64 +340,83 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac val identifiers: MutableList = ArrayList() identifiers.add(identifier) val fipId = sharedVM.consentResponseData.value?.fipId.orEmpty() - onemoney?.discoverAccounts(identifiers, fipId, object : AccountDetailsListener { - override fun onSuccess(accountList: MutableList?) { - hideLoader() - fetchDiscoveredAccounts() - } + onemoney?.discoverAccounts( + identifiers, + fipId, + object : AccountDetailsListener { + override fun onSuccess(accountList: MutableList?) { + hideLoader() + fetchDiscoveredAccounts() + } - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - when (onemoneyError.message) { - context?.getString(R.string.one_money_sdk_account_linked_error_code) -> { - onBackPressed() + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + when (onemoneyError.message) { + context?.getString(R.string.one_money_sdk_account_linked_error_code) -> { + onBackPressed() + } + context?.getString(R.string.one_money_sdk_no_account_found_error_code) -> { + context?.let { + showErrorScreen( + getAggregatorNoDiscoveredAccountErrorData(it), + listOf( + Pair(discoverAccountsRetry, "retry"), + Pair(changeBankClickListener, "error") + ) + ) + } + } + else -> { + context?.let { showErrorScreen(getAggregatorErrorData(it)) } + } } - context?.getString(R.string.one_money_sdk_no_account_found_error_code) -> { + } + } + ) + } + + private val discoverAccountsRetry: View.OnClickListener = + View.OnClickListener { discoverAccounts() } + + private fun fetchDiscoveredAccounts() { + showLoader() + onemoney?.getDiscoveredAccounts( + object : AccountDetailsListener { + override fun onSuccess(accountList: MutableList?) { + hideLoader() + binding.subtitleTv.visibility = View.VISIBLE + sharedVM.resetSelectedAccountData() + val list = accountList ?: mutableListOf() + val filteredDiscoveredAccounts = list.filter { it.data.fipId == fipId } + val linkedAccountsForFip = sharedVM.linkedAccountsForFip.value + binding.bankOtpButton.setState(true) + binding.bankOtpButton.setProperties( + title = activity?.resources?.getString(R.string.link_account).orEmpty() + ) + binding.bankOtpButton.setOnClickListener(bankOtpClickListener) + if ( + !filteredDiscoveredAccounts.isNullOrEmpty() || + !linkedAccountsForFip.isNullOrEmpty() + ) { + sharedVM.processAccountInfo( + filteredDiscoveredAccounts, + linkedAccountsForFip?.toMutableList() + ) + } else { context?.let { showErrorScreen( getAggregatorNoDiscoveredAccountErrorData(it), listOf( - Pair(discoverAccountsRetry, "retry"), + Pair(discoveryClickListener, "retry"), Pair(changeBankClickListener, "error") ) ) } } - else -> { - context?.let { - showErrorScreen(getAggregatorErrorData(it)) - } - } } - } - }) - } - private val discoverAccountsRetry: View.OnClickListener = View.OnClickListener { - discoverAccounts() - } - - private fun fetchDiscoveredAccounts() { - showLoader() - onemoney?.getDiscoveredAccounts(object : AccountDetailsListener { - override fun onSuccess(accountList: MutableList?) { - hideLoader() - binding.subtitleTv.visibility = View.VISIBLE - sharedVM.resetSelectedAccountData() - val list = accountList ?: mutableListOf() - val filteredDiscoveredAccounts = list.filter { it.data.fipId == fipId } - val linkedAccountsForFip = sharedVM.linkedAccountsForFip.value - binding.bankOtpButton.setState(true) - binding.bankOtpButton.setProperties( - title = activity?.resources?.getString(R.string.link_account).orEmpty() - ) - binding.bankOtpButton.setOnClickListener(bankOtpClickListener) - if (!filteredDiscoveredAccounts.isNullOrEmpty() || !linkedAccountsForFip.isNullOrEmpty()) { - sharedVM.processAccountInfo( - filteredDiscoveredAccounts, - linkedAccountsForFip?.toMutableList() - ) - } else { + override fun onFailure(error: OnemoneyError?) { + hideLoader() context?.let { showErrorScreen( getAggregatorNoDiscoveredAccountErrorData(it), @@ -403,27 +428,11 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } } } - - override fun onFailure(error: OnemoneyError?) { - hideLoader() - context?.let { - showErrorScreen( - getAggregatorNoDiscoveredAccountErrorData(it), - listOf( - Pair(discoveryClickListener, "retry"), - Pair(changeBankClickListener, "error") - ) - ) - } - } - } ) } - private val discoveryClickListener: View.OnClickListener = View.OnClickListener { - fetchDiscoveredAccounts() - } - + private val discoveryClickListener: View.OnClickListener = + View.OnClickListener { fetchDiscoveredAccounts() } private fun getExistingSessionId() { showLoader() @@ -431,15 +440,16 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } private fun preProcessFipData() { - onemoney?.getFipList(object : FipListListener { - override fun onFailure(onemoneyError: OnemoneyError) { - // no fip data - } + onemoney?.getFipList( + object : FipListListener { + override fun onFailure(onemoneyError: OnemoneyError) { + // no fip data + } - override fun onSuccess(result: FipList?) { - sharedVM.preProcessFipData(result) + override fun onSuccess(result: FipList?) { + sharedVM.preProcessFipData(result) + } } - } ) } @@ -473,9 +483,10 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } } - sharedVM.oneMoneyProviderConfig.observeNonNull(viewLifecycleOwner, { response -> - makeConsentRequest() - }) + sharedVM.oneMoneyProviderConfig.observeNonNull( + viewLifecycleOwner, + { response -> makeConsentRequest() } + ) sharedVM.selectedAccountData.observeNonNull(this) { if (it.isNullOrEmpty()) { @@ -508,9 +519,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac sharedVM.consentResponseData.observeNullable(this) { hideLoader() - it?.let { - getExistingSessionId() - } + it?.let { getExistingSessionId() } } sharedVM.financialDataStatusAsyncResponse.observeNonNull(this) { response -> @@ -534,13 +543,17 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac sharedVM.errorAsyncResponse.observeNonNull(viewLifecycleOwner) { when (it) { AggregatorSharedVM.ErrorType.BANK_STATEMENT_UPLOAD_LIMIT_EXHAUSTED.name -> { - var nextCtaUrl = NaviDeepLinkNavigator.LOAN_APPLICATION.appendStrings( - FORWARD_SLASH.toString(), - GetLoanActivity.LOAN_OFFER_UPGRADE_SCREEN - ) - if (arguments?.getString(FLOW_TYPE) == BankStatementV2Fragment.BANK_STATEMENT_V2) { - nextCtaUrl = LOAN_APPLICATION_V2.plus(DIVIDER) - .plus(GetLoanV2ViewHelper.LOAN_OFFER_UPGRADE_V2) + var nextCtaUrl = + NaviDeepLinkNavigator.LOAN_APPLICATION.appendStrings( + FORWARD_SLASH.toString(), + GetLoanActivity.LOAN_OFFER_UPGRADE_SCREEN + ) + if ( + arguments?.getString(FLOW_TYPE) == BankStatementV2Fragment.BANK_STATEMENT_V2 + ) { + nextCtaUrl = + LOAN_APPLICATION_V2.plus(DIVIDER) + .plus(GetLoanV2ViewHelper.LOAN_OFFER_UPGRADE_V2) } NaviDeepLinkNavigator.navigate( activity = activity, @@ -551,7 +564,9 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } AggregatorSharedVM.ErrorType.BANK_STATEMENT_SOFT_REJECT.name -> { var nextCtaUrl = NaviDeepLinkNavigator.ERROR - if (arguments?.getString(FLOW_TYPE) == BankStatementV2Fragment.BANK_STATEMENT_V2) { + if ( + arguments?.getString(FLOW_TYPE) == BankStatementV2Fragment.BANK_STATEMENT_V2 + ) { nextCtaUrl = NaviDeepLinkNavigator.ERROR_V2 } val data = Bundle() @@ -570,24 +585,24 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac private fun checkVua() { showLoader() - onemoney?.verifyVUA(userVua, object : ResultListener { - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) + onemoney?.verifyVUA( + userVua, + object : ResultListener { + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + context?.let { showErrorScreen(getAggregatorErrorData(it)) } + } + + override fun onSuccess(result: Boolean) { + hideLoader() + if (result) { + initiateOneMoneyLoginFlow() + } else { + initiateOneMoneySignupFlow() + } } } - - override fun onSuccess(result: Boolean) { - hideLoader() - if (result) { - initiateOneMoneyLoginFlow() - } else { - initiateOneMoneySignupFlow() - } - } - - }) + ) } private fun initiateOneMoneySignupFlow() { @@ -597,7 +612,6 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac UserManager.getPhoneNumber(), true, userVua, - object : UserDetailsListener { override fun onSuccess(p0: ResponseBody?) { hideLoader() @@ -609,13 +623,16 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac { binding.otpView.clearOTP() initiateOneMoneySignupFlow() - }, true + }, + true ) binding.titleTv.visibility = View.GONE binding.subtitleTv.visibility = View.GONE binding.aaRecyclerView.visibility = View.GONE binding.bankInfoItem.root.visibility = View.GONE - binding.bankOtpButton.setProperties(title = resources.getString(R.string.verify)) + binding.bankOtpButton.setProperties( + title = resources.getString(R.string.verify) + ) binding.bankOtpButton.setOnClickListener { verifySignUpOtp( p0?.otp_reference.orEmpty(), @@ -626,11 +643,10 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac override fun onFailure(p0: OnemoneyError?) { hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } - }) + } + ) } private fun verifySignUpOtp(result: String, otp: String) { @@ -640,67 +656,61 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac mobileNo = UserManager.getPhoneNumber(), otpReference = otpReference, otp = otp, - listener = object : UserDetailsListener { - override fun onSuccess(p0: ResponseBody?) { - hideLoader() - initOneMoneySdk(p0?.sessionId) - binding.titleTv.visibility = View.VISIBLE - binding.subtitleTv.visibility = View.VISIBLE - binding.aaRecyclerView.visibility = View.VISIBLE - binding.bankInfoItem.root.visibility = View.VISIBLE - binding.otpView.visibility = View.GONE - sharedVM.saveSessionId( - GenerateSessionRequest( - UserManager.getPhoneNumber(), - p0?.sessionId + listener = + object : UserDetailsListener { + override fun onSuccess(p0: ResponseBody?) { + hideLoader() + initOneMoneySdk(p0?.sessionId) + binding.titleTv.visibility = View.VISIBLE + binding.subtitleTv.visibility = View.VISIBLE + binding.aaRecyclerView.visibility = View.VISIBLE + binding.bankInfoItem.root.visibility = View.VISIBLE + binding.otpView.visibility = View.GONE + sharedVM.saveSessionId( + GenerateSessionRequest(UserManager.getPhoneNumber(), p0?.sessionId) ) - ) - } + } - override fun onFailure(p0: OnemoneyError?) { - hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) + override fun onFailure(p0: OnemoneyError?) { + hideLoader() + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } } - } ) } } - private fun initiateOneMoneyLoginFlow() { showLoader() - onemoney?.loginUser(UserManager.getPhoneNumber(), object : SessionListener { - override fun onSuccess(result: String?) { - hideLoader() - binding.otpView.visibility = View.VISIBLE - binding.otpView.setProperties( - getString(R.string.enter_onemoney_otp_text), - UserManager.getPhoneNumber(), - { - initiateOneMoneyLoginFlow() - }, - true - ) - binding.titleTv.visibility = View.GONE - binding.subtitleTv.visibility = View.GONE - binding.aaRecyclerView.visibility = View.GONE - binding.bankInfoItem.root.visibility = View.GONE - binding.bankOtpButton.setProperties(title = getString(R.string.verify)) - binding.bankOtpButton.setState(false) - binding.bankOtpButton.setOnClickListener { - verifyLoginOTP(result, binding.otpView.otpTrigger.value.orEmpty()) + onemoney?.loginUser( + UserManager.getPhoneNumber(), + object : SessionListener { + override fun onSuccess(result: String?) { + hideLoader() + binding.otpView.visibility = View.VISIBLE + binding.otpView.setProperties( + getString(R.string.enter_onemoney_otp_text), + UserManager.getPhoneNumber(), + { initiateOneMoneyLoginFlow() }, + true + ) + binding.titleTv.visibility = View.GONE + binding.subtitleTv.visibility = View.GONE + binding.aaRecyclerView.visibility = View.GONE + binding.bankInfoItem.root.visibility = View.GONE + binding.bankOtpButton.setProperties(title = getString(R.string.verify)) + binding.bankOtpButton.setState(false) + binding.bankOtpButton.setOnClickListener { + verifyLoginOTP(result, binding.otpView.otpTrigger.value.orEmpty()) + } } - } - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } } - }) + ) } private fun verifyLoginOTP(result: String?, otp: String) { @@ -710,52 +720,55 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac mobileNo = UserManager.getPhoneNumber(), otpReference = otpReference, code = otp, - listener = object : LoginOtpListener { - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) + listener = + object : LoginOtpListener { + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + context?.let { showErrorScreen(getAggregatorErrorData(it)) } + } + + override fun onSuccess(result: LoginOtpResponse) { + hideLoader() + binding.titleTv.visibility = View.VISIBLE + binding.subtitleTv.visibility = View.VISIBLE + binding.aaRecyclerView.visibility = View.VISIBLE + binding.bankInfoItem.root.visibility = View.VISIBLE + binding.otpView.visibility = View.GONE + initOneMoneySdk(result.sessionId) + sharedVM.saveSessionId( + GenerateSessionRequest( + UserManager.getPhoneNumber(), + result.sessionId + ) + ) } } - - override fun onSuccess(result: LoginOtpResponse) { - hideLoader() - binding.titleTv.visibility = View.VISIBLE - binding.subtitleTv.visibility = View.VISIBLE - binding.aaRecyclerView.visibility = View.VISIBLE - binding.bankInfoItem.root.visibility = View.VISIBLE - binding.otpView.visibility = View.GONE - initOneMoneySdk(result.sessionId) - sharedVM.saveSessionId( - GenerateSessionRequest( - UserManager.getPhoneNumber(), - result.sessionId - ) - ) - } - }) + ) } } private fun fetchLinkedAccount(onSuccess: () -> Unit = {}, onFailure: () -> Unit = {}) { - onemoney?.getAccountsLinked(object : AccountDetailsListener { - override fun onSuccess(accountList: MutableList?) { - hideLoader() - val linkedAccountsFip = accountList?.filter { it.data.fipId == fipId } - sharedVM.updateLinkedAccountsFip(linkedAccountsFip) - sharedVM.updateLinkedAccounts(accountList) - onSuccess.invoke() - } + onemoney?.getAccountsLinked( + object : AccountDetailsListener { + override fun onSuccess(accountList: MutableList?) { + hideLoader() + val linkedAccountsFip = accountList?.filter { it.data.fipId == fipId } + sharedVM.updateLinkedAccountsFip(linkedAccountsFip) + sharedVM.updateLinkedAccounts(accountList) + onSuccess.invoke() + } - override fun onFailure(error: OnemoneyError?) { - hideLoader() - onFailure.invoke() + override fun onFailure(error: OnemoneyError?) { + hideLoader() + onFailure.invoke() + } } - }) + ) } // refresh content with consent details - // param: fetchLinkedAccount controls whether to get fresh linked account list from onemoney or not. + // param: fetchLinkedAccount controls whether to get fresh linked account list from onemoney or + // not. private fun showConsentScreen(fetchLinkedAccount: Boolean = false) { binding.bankInfoItem.root.visibility = View.GONE binding.bankInfoItem.aaBankNameIv.visibility = View.INVISIBLE @@ -776,9 +789,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac fetchLinkedAccount( onSuccess = { if (sharedVM.linkedAccounts.value?.isEmpty().orFalse()) { - context?.let { - showErrorScreen(getAggregatorLinkedErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorLinkedErrorData(it)) } } else { processFipListInfo() getConsentDetails() @@ -786,9 +797,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac }, onFailure = { if (sharedVM.linkedAccounts.value?.isEmpty().orFalse()) { - context?.let { - showErrorScreen(getAggregatorLinkedErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorLinkedErrorData(it)) } } } ) @@ -796,41 +805,43 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac processFipListInfo() getConsentDetails() } - } private fun getConsentDetails() { showLoader() val consentHandle = sharedVM.consentResponseData.value?.consentHandle if (consentHandle != null) { - onemoney?.getConsentDetails(listOf(consentHandle), object : ConsentDetailsListener { - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - binding.consentDetails.visibility = View.GONE - } + onemoney?.getConsentDetails( + listOf(consentHandle), + object : ConsentDetailsListener { + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + binding.consentDetails.visibility = View.GONE + } - override fun onSuccess(result: ConsentDetailsResponse) { - hideLoader() - if (result.consentDetails.isNullOrEmpty().not()) { - isOnConsentScreen = true - binding.consentDetails.setProperties(result.consentDetails[0]) - binding.consentDetails.visibility = View.VISIBLE - } else { - synchronized(isConsentAvailableErrorShown) { - if (isConsentAvailableErrorShown.not()) { - isConsentAvailableErrorShown = true - context?.let { - sharedVM.setError( - errors = listOf(getErrorData(context = it)), - tag = GENERAL_ERROR, - cancelable = false - ) + override fun onSuccess(result: ConsentDetailsResponse) { + hideLoader() + if (result.consentDetails.isNullOrEmpty().not()) { + isOnConsentScreen = true + binding.consentDetails.setProperties(result.consentDetails[0]) + binding.consentDetails.visibility = View.VISIBLE + } else { + synchronized(isConsentAvailableErrorShown) { + if (isConsentAvailableErrorShown.not()) { + isConsentAvailableErrorShown = true + context?.let { + sharedVM.setError( + errors = listOf(getErrorData(context = it)), + tag = GENERAL_ERROR, + cancelable = false + ) + } } } } } } - }) + ) } } @@ -840,7 +851,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac binding.rejectConsentBtn.text = getString(R.string.reject) } - //on back press + // on back press private fun showLinkingScreen() { binding.bankInfoItem.root.visibility = View.VISIBLE binding.bankInfoItem.aaBankNameIv.visibility = View.VISIBLE @@ -885,31 +896,27 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac sharedVM.resetData() val consentHandle = sharedVM.consentResponseData.value?.consentHandle val accountList = sharedVM.consentAccountData.value - if (!consentHandle.isNullOrEmpty() - && !accountList.isNullOrEmpty() - ) { + if (!consentHandle.isNullOrEmpty() && !accountList.isNullOrEmpty()) { onemoney?.approveConsentWithoutOTP( consentHandle, accountList, object : ResultListener { override fun onFailure(onemoneyError: OnemoneyError) { hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } override fun onSuccess(result: Boolean) { // handle consent success - sharedVM.verifyFinancialDataStatus(FlagUpdateRequest(referenceId = consentHandle)) + sharedVM.verifyFinancialDataStatus( + FlagUpdateRequest(referenceId = consentHandle) + ) } } ) } else { hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } } @@ -922,9 +929,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac object : ResultListener { override fun onFailure(onemoneyError: OnemoneyError) { hideLoader() - context?.let { - showErrorScreen(getAggregatorErrorData(it)) - } + context?.let { showErrorScreen(getAggregatorErrorData(it)) } } override fun onSuccess(result: Boolean) { @@ -944,12 +949,8 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac if (arguments?.getString(FLOW_TYPE) == BankStatementV2Fragment.BANK_STATEMENT_V2) { activity?.finish() } else { - fragmentInterchangeListener?.navigateToNextScreen( - BANK_STATEMENT_VERIFICATION, - Bundle() - ) + fragmentInterchangeListener?.navigateToNextScreen(BANK_STATEMENT_VERIFICATION, Bundle()) } - } override fun onBackPressed() { @@ -978,17 +979,11 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac rejectConsent() } - override fun secondaryButtonClick() { - - } + override fun secondaryButtonClick() {} private fun makeConsentRequest() { sharedVM.requestConsent( - ConsentRequest( - UserManager.getPhoneNumber(), - fipId.orEmpty(), - CONSENT_INITIATOR_PL - ) + ConsentRequest(UserManager.getPhoneNumber(), fipId.orEmpty(), CONSENT_INITIATOR_PL) ) } @@ -996,73 +991,76 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac val accountList = sharedVM.selectedAccountData.value if (!accountList.isNullOrEmpty()) { showLoader() - onemoney?.sendOtpToLinkBulkAccounts(accountList, object : AuthSessionListener { - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - Timber.i(onemoneyError) - if (onemoneyError.message != null) { - activity?.runOnUiThread { - context?.toast(onemoneyError.message) + onemoney?.sendOtpToLinkBulkAccounts( + accountList, + object : AuthSessionListener { + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + Timber.i(onemoneyError) + if (onemoneyError.message != null) { + activity?.runOnUiThread { context?.toast(onemoneyError.message) } + } + } + + override fun onSuccess(result: AuthSessionParams?) { + hideLoader() + if (result != null) { + sharedVM.updateAuthSessionParams(result) + binding.otpView.visibility = View.VISIBLE + binding.otpView.setProperties( + activity?.resources?.getString(R.string.enter_bank_otp_text) + ?: "Enter bank OTP", + null, + { sendOtpToLinkAccount() }, + false, + R.style.LargeFormElementFontStyle + ) + binding.otpView.requestFocus() + binding.bankOtpButton.setProperties(title = getString(R.string.verify)) + binding.bankOtpButton.setState(false) + binding.bankOtpButton.setOnClickListener { + verifyBankLinkOtp(binding.otpView.otpTrigger.value.orEmpty()) + } + } else { + // handle unknown case } } } - - override fun onSuccess(result: AuthSessionParams?) { - hideLoader() - if (result != null) { - sharedVM.updateAuthSessionParams(result) - binding.otpView.visibility = View.VISIBLE - binding.otpView.setProperties( - activity?.resources?.getString(R.string.enter_bank_otp_text) - ?: "Enter bank OTP", - null, - { sendOtpToLinkAccount() }, false, - R.style.LargeFormElementFontStyle - ) - binding.otpView.requestFocus() - binding.bankOtpButton.setProperties(title = getString(R.string.verify)) - binding.bankOtpButton.setState(false) - binding.bankOtpButton.setOnClickListener { - verifyBankLinkOtp(binding.otpView.otpTrigger.value.orEmpty()) - } - } else { - // handle unknown case - } - } - }) - + ) } } private fun verifyBankLinkOtp(otp: String) { NaviTrackEvent.setStartTs(screenName) showLoader() - onemoney?.verifyOtpToLinkAccount(sharedVM.authSessionParams.value?.refNumber ?: EMPTY, + onemoney?.verifyOtpToLinkAccount( + sharedVM.authSessionParams.value?.refNumber ?: EMPTY, authToken = otp, - listener = object : ResultListener { - override fun onFailure(onemoneyError: OnemoneyError) { - hideLoader() - Timber.i(onemoneyError) - activity?.runOnUiThread { - if (onemoneyError.message != null) - context?.toast(onemoneyError.message) - } - } - - override fun onSuccess(result: Boolean) { - hideLoader() - if (result) { - binding.otpView.visibility = View.GONE - sharedVM.dismissBottomsheet() - sharedVM.clearAllSelectedAccountData() - showConsentScreen(true) - } else { + listener = + object : ResultListener { + override fun onFailure(onemoneyError: OnemoneyError) { + hideLoader() + Timber.i(onemoneyError) activity?.runOnUiThread { - context?.toast(resources.getString(R.string.onemoney_incorrect_otp)) + if (onemoneyError.message != null) context?.toast(onemoneyError.message) + } + } + + override fun onSuccess(result: Boolean) { + hideLoader() + if (result) { + binding.otpView.visibility = View.GONE + sharedVM.dismissBottomsheet() + sharedVM.clearAllSelectedAccountData() + showConsentScreen(true) + } else { + activity?.runOnUiThread { + context?.toast(resources.getString(R.string.onemoney_incorrect_otp)) + } } } } - }) + ) } override fun onResume() { @@ -1099,10 +1097,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac private fun apiPollInit(requestId: String, numOfRetries: Int) { apiPollScheduler = - ApiPollScheduler( - numberOfRetry = numOfRetries, - doOnTimeout = onPollingEnd - ) { + ApiPollScheduler(numberOfRetry = numOfRetries, doOnTimeout = onPollingEnd) { sharedVM.checkApiPollStatus(requestId) } apiPollScheduler?.scheduleApiPoll() @@ -1112,10 +1107,9 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } private fun onPollingResponse(status: String?, isPolling: Boolean = true) { - if (TextUtils.equals(status, FirebaseStatusType.SUCCESS) - || TextUtils.equals( - status, FirebaseStatusType.FAILURE - ) + if ( + TextUtils.equals(status, FirebaseStatusType.SUCCESS) || + TextUtils.equals(status, FirebaseStatusType.FAILURE) ) { hideLoader() deInitializeFirebaseListener() @@ -1125,12 +1119,13 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac TextUtils.equals(status, FirebaseStatusType.SUCCESS) -> { val channelList = ArrayList() channelList.add(IntentConstants.BANK_OFFER) - val bundle = Bundle().apply { - putStringArrayList( - IntentConstants.OFFER_IMPROVEMENT_CHANNEL_TYPE, - channelList - ) - } + val bundle = + Bundle().apply { + putStringArrayList( + IntentConstants.OFFER_IMPROVEMENT_CHANNEL_TYPE, + channelList + ) + } sharedVM.consentResponseData.value?.cta?.let { NaviDeepLinkNavigator.navigate( requireActivity(), @@ -1151,23 +1146,23 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac } private fun firebaseInit(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onPollingResponse(it.status.orEmpty(), false) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { onPollingResponse(it.status.orEmpty(), false) } } } - } firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - FINANCIAL_DATA_STATUS, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + FINANCIAL_DATA_STATUS, + requestId, + notificationPath + ) + } } private fun deInitializeFirebaseListener() { @@ -1181,10 +1176,7 @@ class AccountAggregatorFragment : BaseFragment(), FooterInteractionListener, Bac companion object { fun newInstance(bundle: Bundle): AccountAggregatorFragment { - return AccountAggregatorFragment().apply { - arguments = bundle - } + return AccountAggregatorFragment().apply { arguments = bundle } } } } - diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/viewmodels/BankDetailsVM.kt b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/viewmodels/BankDetailsVM.kt index 51f1a45b63..7c85a15774 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/viewmodels/BankDetailsVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/bankdetails/viewmodels/BankDetailsVM.kt @@ -70,6 +70,8 @@ class BankDetailsVM(private val repository: BankDetailsRepository = BankDetailsR val invalidBankCode: LiveData get() = _invalidBankCode + val toastId = MutableLiveData(null) + fun addBankDetail(bankDetail: BankDetail, loanApplicationId: String, loanType: String?) { coroutineScope.launch { val response = repository.submitBankDetails(bankDetail, loanApplicationId, loanType) diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/common/fragment/CustomerSupportFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/common/fragment/CustomerSupportFragment.kt index 26303faed7..3f3657ac63 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/common/fragment/CustomerSupportFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/common/fragment/CustomerSupportFragment.kt @@ -26,6 +26,7 @@ import com.navi.chat.utils.DEFAULT_SOURCE_ID_FOR_PL import com.navi.chat.utils.NAVI_CHAT_SYSTEM_LOCAL_DATA import com.navi.common.ui.fragment.BaseBottomSheet import com.navi.common.utils.observeNonNull +import com.navi.navi_vkyc.util.VkycNaviAnalytics.Companion.VKYC_WAITING_FOR_EXECUTIVE_SCREEN import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.navigator.ScreenNavigator @@ -211,45 +212,52 @@ class CustomerSupportFragment : BaseBottomSheet(), View.OnClickListener { } private fun navigateToFaqs() { - val faqsData = when (arguments?.getString(CUST_SCREEN_NAME)) { - NaviAnalytics.LOAN_DETAILS -> loanDetailsFaqs(requireContext()) - NaviAnalytics.LOAN_DETAILS_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.KYC -> kycFaqs(requireContext()) - NaviAnalytics.KYC_V2 -> kycFaqs(requireContext()) - NaviAnalytics.BANK_DETAILS -> bankDetailsFaqs(requireContext()) - NaviAnalytics.BANK_DETAILS_V2 -> bankDetailsFaqs(requireContext()) - NaviAnalytics.BANK_DETAIL_AUTO_DEBIT -> bankDetailsAutoDebitFaqs(requireContext()) - NaviAnalytics.BANK_DETAIL_AUTO_DEBIT_V2 -> bankDetailsAutoDebitFaqs(requireContext()) - NaviAnalytics.LOAN_AGREEMENT -> getLoanFaqs(requireContext()) - NaviAnalytics.LOAN_AGREEMENT_VIEW_V2 -> getLoanFaqs(requireContext()) - NaviAnalytics.MFI_CONSENT_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.MFI_CONSENT_SCREEN_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.GET_LOAN_V2_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.LOAN_DETAILS_EDITOR_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.LOAN_ONBOARDING_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PERMISSIONS_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PERMISSIONS_V2_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.GST_VERIFICATION_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.GST_VERIFICATION_FRAGMENT_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.GST_VERIFICATION_FRAGMENT_PASSWORD_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.INTERMEDIATE_V2_VERIFICATION_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.BANK_STATEMENT_FRAGMENT_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.BANK_STATEMENT_PAGE_LANDS -> loanDetailsFaqs(requireContext()) - NaviAnalytics.TELCO_OTP_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.TELCO_OTP_SCREEN_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.ENACH_TUTORIAL_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PART_PRE_PAYMENT_CUSTOM_AMOUNT_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PART_PRE_PAYMENT_TYPE_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PART_PRE_PAYMENT_EMI_CALENDAR_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.REWARD_INFO_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.REWARD_SUMMARY_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.TRACKER_SCREEN -> bankDetailsAutoDebitFaqs(requireContext()) - NaviAnalytics.LOAN_OFFER_UPGRADE_V2_SCREEN -> loanDetailsFaqs(requireContext()) - NaviAnalytics.SELFIE_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.PL_GETLOAN_PAGE_LANDS_V2 -> loanDetailsFaqs(requireContext()) - NaviAnalytics.VIDEO_KYC_V2 -> loanDetailsFaqs(requireContext()) - else -> null - } + val faqsData = + when (arguments?.getString(CUST_SCREEN_NAME)) { + NaviAnalytics.LOAN_DETAILS -> loanDetailsFaqs(requireContext()) + NaviAnalytics.LOAN_DETAILS_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.KYC -> kycFaqs(requireContext()) + NaviAnalytics.KYC_V2 -> kycFaqs(requireContext()) + NaviAnalytics.BANK_DETAILS -> bankDetailsFaqs(requireContext()) + NaviAnalytics.BANK_DETAILS_V2 -> bankDetailsFaqs(requireContext()) + NaviAnalytics.BANK_DETAIL_AUTO_DEBIT -> bankDetailsAutoDebitFaqs(requireContext()) + NaviAnalytics.BANK_DETAIL_AUTO_DEBIT_V2 -> + bankDetailsAutoDebitFaqs(requireContext()) + NaviAnalytics.LOAN_AGREEMENT -> getLoanFaqs(requireContext()) + NaviAnalytics.LOAN_AGREEMENT_VIEW_V2 -> getLoanFaqs(requireContext()) + NaviAnalytics.MFI_CONSENT_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.MFI_CONSENT_SCREEN_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.GET_LOAN_V2_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.LOAN_DETAILS_EDITOR_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.LOAN_ONBOARDING_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.PERMISSIONS_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.PERMISSIONS_V2_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.GST_VERIFICATION_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.GST_VERIFICATION_FRAGMENT_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.GST_VERIFICATION_FRAGMENT_PASSWORD_V2 -> + loanDetailsFaqs(requireContext()) + NaviAnalytics.INTERMEDIATE_V2_VERIFICATION_SCREEN -> + loanDetailsFaqs(requireContext()) + NaviAnalytics.BANK_STATEMENT_FRAGMENT_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.BANK_STATEMENT_PAGE_LANDS -> loanDetailsFaqs(requireContext()) + NaviAnalytics.TELCO_OTP_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.TELCO_OTP_SCREEN_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.ENACH_TUTORIAL_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.PART_PRE_PAYMENT_CUSTOM_AMOUNT_SCREEN -> + loanDetailsFaqs(requireContext()) + NaviAnalytics.PART_PRE_PAYMENT_TYPE_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.PART_PRE_PAYMENT_EMI_CALENDAR_SCREEN -> + loanDetailsFaqs(requireContext()) + NaviAnalytics.REWARD_INFO_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.REWARD_SUMMARY_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.TRACKER_SCREEN -> bankDetailsAutoDebitFaqs(requireContext()) + NaviAnalytics.LOAN_OFFER_UPGRADE_V2_SCREEN -> loanDetailsFaqs(requireContext()) + NaviAnalytics.SELFIE_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.PL_GETLOAN_PAGE_LANDS_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.VIDEO_KYC_V2 -> loanDetailsFaqs(requireContext()) + NaviAnalytics.DELAYED_DISBURSEMENT_DETAILS_V2_SCREEN -> loanDetailsFaqs(requireContext()) + else -> null + } faqsData?.let { val bundle = Bundle().apply { putParcelable(FAQS_DATA, it) } ScreenNavigator.instance.startActivity( @@ -296,7 +304,7 @@ class CustomerSupportFragment : BaseBottomSheet(), View.OnClickListener { NaviAnalytics.PROFILE, NaviAnalytics.WORK_DETAIL, NaviAnalytics.LOAN_DETAILS_V2, - NaviAnalytics.KYC_V2 , + NaviAnalytics.KYC_V2, NaviAnalytics.BANK_DETAILS_V2, NaviAnalytics.BANK_DETAIL_AUTO_DEBIT_V2, NaviAnalytics.LOAN_AGREEMENT_VIEW_V2, @@ -305,8 +313,9 @@ class CustomerSupportFragment : BaseBottomSheet(), View.OnClickListener { NaviAnalytics.LOAN_OFFER_UPGRADE_V2_SCREEN, NaviAnalytics.SELFIE_V2, NaviAnalytics.PL_GETLOAN_PAGE_LANDS_V2, - NaviAnalytics.VIDEO_KYC_V2 - -> true + NaviAnalytics.VIDEO_KYC_V2, + VKYC_WAITING_FOR_EXECUTIVE_SCREEN, + NaviAnalytics.DELAYED_DISBURSEMENT_DETAILS_V2_SCREEN -> true else -> false } } @@ -336,5 +345,4 @@ class CustomerSupportFragment : BaseBottomSheet(), View.OnClickListener { } } } - } diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/model/DelayedDisbursement.kt b/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/model/DelayedDisbursement.kt index ca9f3d55c6..48a5852cd9 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/model/DelayedDisbursement.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/model/DelayedDisbursement.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -10,25 +10,16 @@ package com.naviapp.personalloan.getloan.delayedDisbursement.model import com.google.gson.annotations.SerializedName import com.navi.base.model.CtaData - data class DelayedDisbursementDetails( - @SerializedName("content") - val content: List? = null, + @SerializedName("content") val content: List? = null, ) data class DelayedDisbursement( - @SerializedName("title") - val title: String? = null, - @SerializedName("subTitle") - val subTitle: String? = null, - @SerializedName("iconCode") - val iconCode: String? = null, - @SerializedName("colorCode") - val hexCode: String? = null, - @SerializedName("date") - val date: String? = null, - @SerializedName("suggestion") - val suggestion : String? = null, - @SerializedName("cta") - val ctaData : CtaData? = null + @SerializedName("title") val title: String? = null, + @SerializedName("subTitle") val subTitle: String? = null, + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("colorCode") val hexCode: String? = null, + @SerializedName("date") val date: String? = null, + @SerializedName("suggestion") val suggestion: String? = null, + @SerializedName("cta") val ctaData: CtaData? = null ) diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/viewmodels/DelayedDisbursementViewModel.kt b/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/viewmodels/DelayedDisbursementViewModel.kt index c98195c76d..3d05f782a7 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/viewmodels/DelayedDisbursementViewModel.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/delayedDisbursement/viewmodels/DelayedDisbursementViewModel.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -14,14 +14,14 @@ import com.naviapp.personalloan.getloan.delayedDisbursement.model.DelayedDisburs import com.naviapp.personalloan.getloan.delayedDisbursement.repositories.DelayedDisbursementRepository import kotlinx.coroutines.launch -class DelayedDisbursementViewModel(private val repository: DelayedDisbursementRepository = DelayedDisbursementRepository()) : - BaseVM() { +class DelayedDisbursementViewModel( + private val repository: DelayedDisbursementRepository = DelayedDisbursementRepository() +) : BaseVM() { private val _delayedDisbursementDetails = MutableLiveData() val delayedDisbursementDetails: LiveData get() = _delayedDisbursementDetails - fun fetchDelayedDisbursementDetails(loanApplicationId: String) { coroutineScope.launch { val response = repository.fetchDelayedDisbursementDetails(loanApplicationId) @@ -32,6 +32,4 @@ class DelayedDisbursementViewModel(private val repository: DelayedDisbursementRe } } } - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/emi/fragments/EMIDateChangeFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/emi/fragments/EMIDateChangeFragment.kt index 66ecc91847..63974ee455 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/emi/fragments/EMIDateChangeFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/emi/fragments/EMIDateChangeFragment.kt @@ -9,19 +9,25 @@ package com.naviapp.personalloan.getloan.emi.fragments import android.content.Context import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import androidx.core.widget.addTextChangedListener import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.CtaData +import com.navi.base.utils.isNotNullAndNotEmpty import com.navi.common.extensions.orFalse import com.navi.common.listeners.HeaderInteractionListener import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.observeNonNull +import com.navi.design.utils.getNaviDrawable +import com.navi.naviwidgets.validations.RegexInputValidation +import com.navi.naviwidgets.widgets.TextInputUtil +import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.listeners.FooterInteractionListener import com.naviapp.common.listeners.KeyValueListener @@ -30,6 +36,7 @@ import com.naviapp.dashboard.listeners.FragmentInteractionListener import com.naviapp.databinding.EmiDateChangeFragmentBinding import com.naviapp.models.EMIDateChangeResponse import com.naviapp.models.KeyValueResponse +import com.naviapp.models.ReasonConfig import com.naviapp.models.response.LoanBasicDetailsResponse import com.naviapp.personalloan.getloan.emi.adapters.EMIDateAdapter import com.naviapp.personalloan.getloan.emi.viewmodels.EMIDateChangeFragmentVM @@ -87,23 +94,6 @@ class EMIDateChangeFragment : BaseFragment(), FooterInteractionListener { eventTracker.onEmiDateChangePage(loanType) binding.footerView.changeNextButtonBackground(false) headerInteractionListener?.hideHelpIcon() - binding.enterReasonLt.addTextWatcher( - object : TextWatcher { - override fun beforeTextChanged( - s: CharSequence?, - start: Int, - count: Int, - after: Int - ) {} - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} - - override fun afterTextChanged(s: Editable?) { - validateFooterView() - reason = s.toString() - } - } - ) } private fun fetchEMIDateChangeResponse() { @@ -154,12 +144,69 @@ class EMIDateChangeFragment : BaseFragment(), FooterInteractionListener { binding.layoutKeyValue.keyTv.text = title.key binding.layoutKeyValue.valueTv.text = title.value } - binding.enterReasonLt.updateData( - viewModel.getLabeledTextInputWidgetModel( - it.reasonConfig?.header, - it.reasonConfig?.hint - ) + setReason(it.reasonConfig) + } + } + + private fun setReason(reasonConfig: ReasonConfig?) { + binding.plainTextInput.background = + getNaviDrawable( + strokeWidth = resources.getDimension(com.navi.naviwidgets.R.dimen.dp_1).toInt(), + cornerRadius = resources.getDimension(com.navi.naviwidgets.R.dimen.dp_8).toInt(), + strokeColor = + ResourcesCompat.getColor( + resources, + com.navi.naviwidgets.R.color.border_dark_grey_color, + null + ) ) + binding.plainTextInput.hint = reasonConfig?.hint + + binding.titleTv.text = reasonConfig?.header + if (reasonConfig?.header.isNotNullAndNotEmpty()) { + binding.titleTv.visibility = View.VISIBLE + } + binding.errorText.text = reasonConfig?.warningText + if (reasonConfig?.warningText.isNotNullAndNotEmpty()) { + binding.errorText.visibility = View.VISIBLE + context?.let { + binding.errorText.setTextColor( + ContextCompat.getColor(it, R.color.description_grey_color_seven) + ) + binding.errorText.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null) + } + } + + binding.plainTextInput.addTextChangedListener { + validateFooterView() + reason = it.toString() + if (reasonConfig?.warningText.isNotNullAndNotEmpty()) { + binding.errorText.text = reasonConfig?.warningText + binding.errorText.visibility = View.VISIBLE + context?.let { + binding.errorText.setTextColor( + ContextCompat.getColor(it, R.color.description_grey_color_seven) + ) + binding.errorText.setCompoundDrawablesWithIntrinsicBounds( + null, + null, + null, + null + ) + } + } + binding.plainTextInput.background = + getNaviDrawable( + strokeWidth = resources.getDimension(com.navi.naviwidgets.R.dimen.dp_1).toInt(), + cornerRadius = + resources.getDimension(com.navi.naviwidgets.R.dimen.dp_8).toInt(), + strokeColor = + ResourcesCompat.getColor( + resources, + com.navi.naviwidgets.R.color.border_dark_grey_color, + null + ) + ) } } @@ -228,7 +275,7 @@ class EMIDateChangeFragment : BaseFragment(), FooterInteractionListener { private fun validateFooterValues(): Boolean { if (getSelectedDateKey().isNullOrBlank()) { return false - } else if (binding.enterReasonLt.getUserInput().isNullOrBlank()) { + } else if (binding.plainTextInput.text.isNullOrBlank()) { return false } return true @@ -253,10 +300,7 @@ class EMIDateChangeFragment : BaseFragment(), FooterInteractionListener { eventTracker.onChangeEmiDateCTA(date, reason, loanType) val bundle = Bundle() bundle.putString(EMIUpdatedCalendarFragment.KEY_DATE, getSelectedDateKey()) - bundle.putString( - EMIUpdatedCalendarFragment.KEY_REASON, - binding.enterReasonLt.getUserInput() - ) + bundle.putString(EMIUpdatedCalendarFragment.KEY_REASON, reason) arguments?.getString(LOAN_ACCOUNT_NUMBER_DATA)?.let { bundle.putString(LOAN_ACCOUNT_NUMBER_DATA, it) } @@ -281,11 +325,45 @@ class EMIDateChangeFragment : BaseFragment(), FooterInteractionListener { context?.toast(header) } return false - } else if (binding.enterReasonLt.getUserInput().isNullOrBlank()) { - binding.enterReasonLt.setError( - binding.emiDateBinder?.content?.reasonConfig?.validationError - ) + } else if (binding.plainTextInput.text.isNullOrBlank()) { + binding.errorText.text = binding.emiDateBinder?.content?.reasonConfig?.validationError return false + } else if (!binding.plainTextInput.text.isNullOrBlank()) { + val regexInputValidation = RegexInputValidation(TextInputUtil.REGEX_ALPHA_NUMERIC) + val isValid = regexInputValidation.performCheck(binding.plainTextInput.text?.toString()) + if (!isValid) { + binding.plainTextInput.background = + getNaviDrawable( + strokeWidth = + resources.getDimension(com.navi.naviwidgets.R.dimen.dp_1).toInt(), + cornerRadius = + resources.getDimension(com.navi.naviwidgets.R.dimen.dp_8).toInt(), + strokeColor = + ResourcesCompat.getColor( + resources, + com.navi.naviwidgets.R.color.outrageous_orange, + null + ) + ) + binding.errorText.text = binding.emiDateBinder?.content?.reasonConfig?.warningText + if ( + binding.emiDateBinder?.content?.reasonConfig?.warningText.isNotNullAndNotEmpty() + ) { + binding.errorText.visibility = View.VISIBLE + context?.let { + binding.errorText.setTextColor( + ContextCompat.getColor(it, R.color.outrageous_orange) + ) + binding.errorText.setCompoundDrawablesWithIntrinsicBounds( + ContextCompat.getDrawable(it, R.drawable.ic_alert_error_red), + null, + null, + null + ) + } + } + return false + } } return true } diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/emi/viewmodels/EMIDateChangeFragmentVM.kt b/app/src/main/java/com/naviapp/personalloan/getloan/emi/viewmodels/EMIDateChangeFragmentVM.kt index 12e6d0a426..3cee9a9876 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/emi/viewmodels/EMIDateChangeFragmentVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/emi/viewmodels/EMIDateChangeFragmentVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -10,10 +10,6 @@ package com.naviapp.personalloan.getloan.emi.viewmodels import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope -import com.navi.naviwidgets.widgets.TextInputUtil -import com.navi.naviwidgets.widgets.labledtextinput.InputTextWidgetMeta -import com.navi.naviwidgets.widgets.labledtextinput.LabeledTextInputWidgetModelV2 -import com.navi.naviwidgets.widgets.labledtextinput.TextInputWidgetData import com.navi.common.viewmodel.BaseVM import com.naviapp.models.EMIDateChangeResponse import com.naviapp.models.response.LoanBasicDetailsResponse @@ -41,22 +37,6 @@ class EMIDateChangeFragmentVM : BaseVM() { } } - fun getLabeledTextInputWidgetModel( - reasonHeader: String?, - reasonHint:String? - ): LabeledTextInputWidgetModelV2 { - return LabeledTextInputWidgetModelV2( - widgetData = TextInputWidgetData( - inputTextData = InputTextWidgetMeta( - inputType = TextInputUtil.INPUT_TYPE_TEXT_PERSON_NAME, - hint = reasonHint - ) - ).apply { - title = reasonHeader - } - ) - } - fun fetchLoanBasicDetails() { viewModelScope.launch { val response = repository.fetchLoanBasicDetails() @@ -67,4 +47,4 @@ class EMIDateChangeFragmentVM : BaseVM() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/helper/GetLoanViewHelper.kt b/app/src/main/java/com/naviapp/personalloan/getloan/helper/GetLoanViewHelper.kt index 546cedfe9f..12528d87be 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/helper/GetLoanViewHelper.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/helper/GetLoanViewHelper.kt @@ -27,8 +27,7 @@ import com.naviapp.personalloan.getloan.mfi.fragments.MFIConsentFragment import com.naviapp.personalloan.getloan.summary.fragments.SummaryFragment import com.naviapp.utils.Constants -class -GetLoanViewHelper(isSecondLoanJourney: Boolean = false) { +class GetLoanViewHelper(isSecondLoanJourney: Boolean = false) { private var secondLoanTabsShiffting: Int = 0 @@ -49,7 +48,8 @@ GetLoanViewHelper(isSecondLoanJourney: Boolean = false) { GetLoanActivity.QUESTIONNAIRE_SCREEN -> QuestionnaireFragment.TAG GetLoanActivity.ADDRESS_VERIFICATION_SCREEN -> KycAddressFragment.TAG GetLoanActivity.ADDRESS_VERIFICATION_PROOF_SCREEN -> KycAddressProofFragment.TAG - GetLoanActivity.ADDRESS_PHYSICAL_VERIFICATION -> KycPhysicalAddressVerificationFragment.TAG + GetLoanActivity.ADDRESS_PHYSICAL_VERIFICATION -> + KycPhysicalAddressVerificationFragment.TAG GetLoanActivity.PHYSICAL_KYC_SCREEN -> PhysicalKycFragment.TAG GetLoanActivity.EMI_DATE_CHANGE_SCREEN -> EMIDateChangeFragment.TAG GetLoanActivity.UPDATED_EMI_CALENDAR -> EMIUpdatedCalendarFragment.TAG @@ -63,24 +63,22 @@ GetLoanViewHelper(isSecondLoanJourney: Boolean = false) { fun getFragment(screen: String, bundle: Bundle? = null): Fragment? { return when (screen) { GetLoanActivity.LOAN_DETAILS_SCREEN -> LoanDetailsFragment() - GetLoanActivity.LOAN_OFFER_UPGRADE_SCREEN -> LoanOfferUpgradeFragment.newInstance( - bundle - ) + GetLoanActivity.LOAN_OFFER_UPGRADE_SCREEN -> + LoanOfferUpgradeFragment.newInstance(bundle) GetLoanActivity.KYC_SCREEN -> KycFragment() GetLoanActivity.VIDEO_KYC_SCREEN -> VideoKycFragment() GetLoanActivity.PHYSICAL_KYC_SCREEN -> PhysicalKycFragment() - GetLoanActivity.BANK_DETAILS_SCREEN -> BankDetailsFragment.newInstance( - bundle - ) + GetLoanActivity.BANK_DETAILS_SCREEN -> BankDetailsFragment.newInstance(bundle) GetLoanActivity.SUMMARY_SCREEN -> SummaryFragment() - GetLoanActivity.BANK_DETAILS_AUTO_DEBIT_SCREEN -> BankDetailsAutoDebitFragment.newInstance( - bundle - ) + GetLoanActivity.BANK_DETAILS_AUTO_DEBIT_SCREEN -> + BankDetailsAutoDebitFragment.newInstance(bundle) GetLoanActivity.KYC_IN_REVIEW -> KycInReviewFragment() - GetLoanActivity.QUESTIONNAIRE_SCREEN -> QuestionnaireFragment.newInstance(Constants.TYPE_PERSONAL_LOAN) + GetLoanActivity.QUESTIONNAIRE_SCREEN -> + QuestionnaireFragment.newInstance(Constants.TYPE_PERSONAL_LOAN) GetLoanActivity.ADDRESS_VERIFICATION_SCREEN -> KycAddressFragment() GetLoanActivity.ADDRESS_VERIFICATION_PROOF_SCREEN -> KycAddressProofFragment() - GetLoanActivity.ADDRESS_PHYSICAL_VERIFICATION -> KycPhysicalAddressVerificationFragment() + GetLoanActivity.ADDRESS_PHYSICAL_VERIFICATION -> + KycPhysicalAddressVerificationFragment() GetLoanActivity.EMI_DATE_CHANGE_SCREEN -> EMIDateChangeFragment.newInstance(Bundle()) GetLoanActivity.UPDATED_EMI_CALENDAR -> EMIUpdatedCalendarFragment.newInstance(Bundle()) GetLoanActivity.MFI_CONSENT_SCREEN -> MFIConsentFragment() @@ -148,4 +146,4 @@ GetLoanViewHelper(isSecondLoanJourney: Boolean = false) { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/kyc/viewmodels/VideoKycVM.kt b/app/src/main/java/com/naviapp/personalloan/getloan/kyc/viewmodels/VideoKycVM.kt index f50f123003..15e38db1fa 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/kyc/viewmodels/VideoKycVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/kyc/viewmodels/VideoKycVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -10,20 +10,20 @@ package com.naviapp.personalloan.getloan.kyc.viewmodels import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.navi.common.extensions.isNull +import com.navi.common.model.GenericErrorResponse import com.navi.common.model.UploadDataAsyncResponse +import com.navi.common.utils.orTrue import com.navi.common.viewmodel.BaseVM +import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.models.RedirectPageStatus import com.naviapp.models.response.* import com.naviapp.network.ApiConstants -import com.navi.common.model.GenericErrorResponse import com.naviapp.personalloan.getloan.kyc.repositories.VideoKycRepository +import com.naviapp.personalloanrevamp.models.KycDetailsResponseV2 import com.naviapp.personalloanrevamp.models.VideoKycDetailsV2Response import com.naviapp.utils.EMPTY import com.naviapp.utils.getMultipartBody import com.naviapp.utils.getMultipartRequestBody -import com.navi.common.utils.orTrue -import com.naviapp.analytics.utils.NaviAnalytics -import com.naviapp.personalloanrevamp.models.KycDetailsResponseV2 import kotlinx.coroutines.launch import okhttp3.MultipartBody @@ -97,7 +97,6 @@ class VideoKycVM(private val repository: VideoKycRepository = VideoKycRepository } } - fun fetchVideoKycUrl() { coroutineScope.launch { val response = repository.fetchVideoKycUrl() @@ -113,9 +112,7 @@ class VideoKycVM(private val repository: VideoKycRepository = VideoKycRepository coroutineScope.launch { val front = getMultipartBody(ovdFrontSide, OVD_FRONT_SIDE, FRONT) var back: MultipartBody.Part? = null - ovdBackSide?.let { - back = getMultipartBody(ovdBackSide, OVD_BACK_SIDE, BACK) - } + ovdBackSide?.let { back = getMultipartBody(ovdBackSide, OVD_BACK_SIDE, BACK) } val response = repository.submitVideoOvd(front, back, getMultipartRequestBody(type)) if (response.error == null && response.errors?.isEmpty().orTrue()) { _supportedOvdsUpload.value = Pair(type, response.data) diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/EmiSelectorFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/EmiSelectorFragment.kt index 126e956ee6..326b6f64db 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/EmiSelectorFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/EmiSelectorFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -18,20 +18,20 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import com.navi.base.sharedpref.PreferenceManager +import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.model.Money +import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.* import com.navi.design.calendar.adapter.NaviCalendarViewAdapter import com.navi.design.calendar.model.WeekDayData +import com.navi.design.utils.getNaviDrawable import com.navi.design.utils.getTotalNumberOfDayInMonth import com.navi.design.utils.parseDateFromOneToAnother import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.ui.fragment.BaseFragment -import com.navi.common.listeners.HeaderInteractionListener import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.EmiSelectorFragmentBinding import com.naviapp.models.EmiStartDate -import com.navi.common.model.Money -import com.navi.design.utils.getNaviDrawable import com.naviapp.models.request.LoanFeeDetailsRequest import com.naviapp.models.response.EmiCalendarData import com.naviapp.models.response.EmiCalendarDataResponse @@ -56,14 +56,12 @@ class EmiSelectorFragment : BaseFragment() { private var selectedDate: Date? = null private val analyticsEventTracker = NaviAnalytics.naviAnalytics.EmiSelector() - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = EmiSelectorFragmentBinding.inflate( - layoutInflater, container, false - ) + binding = EmiSelectorFragmentBinding.inflate(layoutInflater, container, false) initError(viewModel) initObserver() initListeners() @@ -94,19 +92,22 @@ class EmiSelectorFragment : BaseFragment() { val tenure = arguments?.getInt(TENURE) val productCode = PreferenceManager.getStringPreference(PRODUCT_CODE) - val loanFeeDetailsRequest = LoanFeeDetailsRequest( - amount = loanAmount, - firstEmiDueDate = selectedDate?.let { date -> - formatDateInto(date, DATE_FORMAT_YYYY_MM_DD) - }, - rateOfInterest = rateOfInterest, - tenureInMonths = tenure, - productCode = productCode - ) + val loanFeeDetailsRequest = + LoanFeeDetailsRequest( + amount = loanAmount, + firstEmiDueDate = + selectedDate?.let { date -> + formatDateInto(date, DATE_FORMAT_YYYY_MM_DD) + }, + rateOfInterest = rateOfInterest, + tenureInMonths = tenure, + productCode = productCode + ) - val bundle = Bundle().apply { - putParcelable(LOAN_FEE_DETAILS_REQUEST, loanFeeDetailsRequest) - } + val bundle = + Bundle().apply { + putParcelable(LOAN_FEE_DETAILS_REQUEST, loanFeeDetailsRequest) + } NaviDeepLinkNavigator.navigate(activity = activity, ctaData = it, bundle = bundle) } @@ -116,37 +117,36 @@ class EmiSelectorFragment : BaseFragment() { private fun initUI() { headerInteractionListener?.hideHelpIcon() binding.emiDescriptionTv.makeUnderlined() - binding.infoDescription.rootItem.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_10).toInt(), - backgroundColor = ResourcesCompat.getColor( - resources, - R.color.view_background_color_nine, null - ), - ) + binding.infoDescription.rootItem.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_10).toInt(), + backgroundColor = + ResourcesCompat.getColor(resources, R.color.view_background_color_nine, null), + ) } - private fun initCalendar(emiCalendarData: EmiCalendarData) { - val startDate = parseDateFromOneToAnother( - emiCalendarData.calendarConfig?.startDate, - DATE_FORMAT_YYYY_MM_DD - ) + val startDate = + parseDateFromOneToAnother( + emiCalendarData.calendarConfig?.startDate, + DATE_FORMAT_YYYY_MM_DD + ) arguments?.getString(SELECTED_EMI_DATE)?.let { selectedDate = parseYYYYMMDDStringToDate(it) - } ?: run { - selectedDate = startDate } + ?: run { selectedDate = startDate } - val endDate = parseDateFromOneToAnother( - emiCalendarData.calendarConfig?.endDate, - DATE_FORMAT_YYYY_MM_DD - ) - val defaultDate = arguments?.getString(SELECTED_EMI_DATE)?.let { - parseDateFromOneToAnother(it, DATE_FORMAT_YYYY_MM_DD) - } ?: run { - startDate - } + val endDate = + parseDateFromOneToAnother( + emiCalendarData.calendarConfig?.endDate, + DATE_FORMAT_YYYY_MM_DD + ) + val defaultDate = + arguments?.getString(SELECTED_EMI_DATE)?.let { + parseDateFromOneToAnother(it, DATE_FORMAT_YYYY_MM_DD) + } + ?: run { startDate } if (startDate != null && endDate != null && defaultDate != null) { binding.calendarList.initNaviCalendar(startDate, endDate, defaultDate, null) { @@ -188,21 +188,16 @@ class EmiSelectorFragment : BaseFragment() { binding.actionBtn.setPropertiesUsingCta(it) { selectedDate?.let { analyticsEventTracker.onConfirmEmiClicked( - formatDateInto( - it, - DATE_FORMAT_YYYY_MM_DD - ) + formatDateInto(it, DATE_FORMAT_YYYY_MM_DD) ) } val intent = Intent() intent.putExtra(START_EMI_DATE, formatDateIntoEmiStartDateModel()) - intent.putExtra(SELECTED_EMI_DATE, selectedDate?.let { it1 -> - formatDateInto( - it1, - DATE_FORMAT_YYYY_MM_DD - ) - }) + intent.putExtra( + SELECTED_EMI_DATE, + selectedDate?.let { it1 -> formatDateInto(it1, DATE_FORMAT_YYYY_MM_DD) } + ) activity?.setResult(Activity.RESULT_OK, intent) activity?.finish() } @@ -243,13 +238,14 @@ class EmiSelectorFragment : BaseFragment() { val calendar = Calendar.getInstance() calendar.time = date viewModel.emiOptionalDateInfo.value?.content?.noteData?.let { - binding.infoDescription.titleTxt.text = it.subtitle?.format( - if (calendar.get(Calendar.DAY_OF_MONTH) == totalNumberOfDayInMonth) { - getString(R.string.last_day) - } else { - getDateWithSuffix(calendar) - } - ) + binding.infoDescription.titleTxt.text = + it.subtitle?.format( + if (calendar.get(Calendar.DAY_OF_MONTH) == totalNumberOfDayInMonth) { + getString(R.string.last_day) + } else { + getDateWithSuffix(calendar) + } + ) } } @@ -266,9 +262,6 @@ class EmiSelectorFragment : BaseFragment() { const val SELECTED_EMI_DATE = "SELECTED_EMI_DATE" @JvmStatic - fun newInstance(bundle: Bundle) = - EmiSelectorFragment().apply { - arguments = bundle - } + fun newInstance(bundle: Bundle) = EmiSelectorFragment().apply { arguments = bundle } } } diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/LoanOfferUpgradeFragment.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/LoanOfferUpgradeFragment.kt index 5f8298f042..7350890bbb 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/LoanOfferUpgradeFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/fragments/LoanOfferUpgradeFragment.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloan.getloan.loandetails.fragments import android.content.Context @@ -7,8 +14,8 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent -import com.navi.common.listeners.HeaderInteractionListener import com.navi.base.model.CtaData +import com.navi.common.listeners.HeaderInteractionListener import com.navi.common.ui.fragment.BaseFragment import com.navi.common.ui.fragment.CommonDialogBox import com.navi.common.utils.observeNonNull @@ -59,9 +66,7 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View arguments?.getParcelable(Constants.KEY_CTA)?.let { it.parameters?.let { parameters -> parameters.forEach { item -> - item.key?.let { key -> - ctaQueryMap[key] = "${item.value}" - } + item.key?.let { key -> ctaQueryMap[key] = "${item.value}" } } ctaQueryMap[Constants.KEY_CURRENT_SCREEN] = GetLoanActivity.BANK_DETAILS_SCREEN } @@ -82,17 +87,14 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View this ) - offerUpgradeResponse.content?.popUpInfo?.let { - displayOfferDialog(it) - } + offerUpgradeResponse.content?.popUpInfo?.let { displayOfferDialog(it) } offerUpgradeResponse.content?.let { offerUpgradeDetails -> offerUpgradeDetails.loanOfferBenefitCardData?.let { binding.offerUpgradeBenefitsCardView.visibility = View.VISIBLE binding.offerUpgradeBenefitsCardView.setProperties(it) - } ?: run { - binding.offerUpgradeBenefitsCardView.visibility = View.GONE } + ?: run { binding.offerUpgradeBenefitsCardView.visibility = View.GONE } context?.let { offerUpgradeDetails.offerImprovementCardsList?.forEach { element -> if (element.verified == true) { @@ -103,18 +105,17 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View offerImprovementCardView.setProperties(element) offerImprovementCardView.setOnClickListener { if (element.cardType == BANK_STATEMENT_CARD) { - offerUpgradeDetails.popUpInfo?.let { - displayOfferDialog(it) - } + offerUpgradeDetails.popUpInfo?.let { displayOfferDialog(it) } } analyticsEventTracker.onOfferImprovementCardClick(element.title) NaviDeepLinkNavigator.navigate( requireActivity(), ctaData = CtaData(url = element.cta?.url), - bundle = Bundle().apply { - putBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE, true) - putString(EPFO_PAGE_TYPE, OFFER_UPGRADE) - } + bundle = + Bundle().apply { + putBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE, true) + putString(EPFO_PAGE_TYPE, OFFER_UPGRADE) + } ) } binding.offerImprovementCardView.addView( @@ -129,9 +130,7 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View } val offerUpgradeCardList = mutableListOf() offerUpgradeResponse.content?.offerImprovementCardsList?.forEach { - it.title?.apply { - offerUpgradeCardList.add(this) - } + it.title?.apply { offerUpgradeCardList.add(this) } } analyticsEventTracker.sendOfferTypeCards(offerUpgradeCardList.toList()) } @@ -139,27 +138,29 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View private fun displayOfferDialog(popUpInfo: PopUpInfo) { analyticsEventTracker.onNoUpgradePopupShown() - val commonDialogBox = CommonDialogBox.newInstance( - screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, - title = popUpInfo.title, - description = popUpInfo.subTitle, - ctaData = popUpInfo.cta, - iconCode = popUpInfo.iconCode, - isCancelable = false - ) + val commonDialogBox = + CommonDialogBox.newInstance( + screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, + title = popUpInfo.title, + description = popUpInfo.subTitle, + ctaData = popUpInfo.cta, + iconCode = popUpInfo.iconCode, + isCancelable = false + ) safelyShowDialogBox(commonDialogBox, CommonDialogBox.TAG) } private fun displayOfferDialog(offerUpgradeGreetingResponse: OfferUpgradeGreetingResponse) { analyticsEventTracker.onNoUpgradePopupShown() - val commonDialogBox = CommonDialogBox.newInstance( - screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, - title = offerUpgradeGreetingResponse.title, - description = offerUpgradeGreetingResponse.description, - ctaData = offerUpgradeGreetingResponse.nextCta, - iconCode = offerUpgradeGreetingResponse.iconCode, - isCancelable = false - ) + val commonDialogBox = + CommonDialogBox.newInstance( + screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, + title = offerUpgradeGreetingResponse.title, + description = offerUpgradeGreetingResponse.description, + ctaData = offerUpgradeGreetingResponse.nextCta, + iconCode = offerUpgradeGreetingResponse.iconCode, + isCancelable = false + ) safelyShowDialogBox(commonDialogBox, CommonDialogBox.TAG) } @@ -178,21 +179,13 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View } override fun onFooterBackPress(ctaData: CtaData?) { - ctaData?.url?.let { - listener?.navigateTo( - it - ) - } + ctaData?.url?.let { listener?.navigateTo(it) } } override fun onFooterNextPress(ctaData: CtaData?, skipValidation: Boolean?) { analyticsEventTracker.onNextButtonClick() NaviTrackEvent.setStartTs(screenName) - ctaData?.url?.let { - listener?.navigateTo( - it - ) - } + ctaData?.url?.let { listener?.navigateTo(it) } } override fun onAttach(context: Context) { @@ -214,9 +207,7 @@ class LoanOfferUpgradeFragment : BaseFragment(), FooterInteractionListener, View const val BANK_STATEMENT_CARD = "BANK_STATEMENT" fun newInstance(bundle: Bundle?): LoanOfferUpgradeFragment { - return LoanOfferUpgradeFragment().apply { - arguments = bundle - } + return LoanOfferUpgradeFragment().apply { arguments = bundle } } } } diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/EffectiveInterestCostRepository.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/EffectiveInterestCostRepository.kt index 854ebe2200..b71c576eeb 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/EffectiveInterestCostRepository.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/EffectiveInterestCostRepository.kt @@ -11,10 +11,10 @@ import com.naviapp.network.retrofit.ResponseCallback import com.naviapp.network.retrofit.RetrofitService import javax.inject.Inject -class EffectiveInterestCostRepository @Inject constructor( - private val retrofitService: RetrofitService -) : ResponseCallback() { +class EffectiveInterestCostRepository +@Inject +constructor(private val retrofitService: RetrofitService) : ResponseCallback() { suspend fun fetchEffectiveInterestInfo(bodyMap: HashMap) = apiResponseCallback(retrofitService.fetchEffectiveInterestInfo(bodyMap)) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanDetailsRepository.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanDetailsRepository.kt index 24b49e4f97..7723825e5c 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanDetailsRepository.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanDetailsRepository.kt @@ -16,8 +16,7 @@ import com.naviapp.utils.retrofitService class LoanDetailsRepository : ResponseCallback() { - suspend fun fetchEmiStartDates() = - apiResponseCallback(retrofitService().fetchEmiStartDates()) + suspend fun fetchEmiStartDates() = apiResponseCallback(retrofitService().fetchEmiStartDates()) suspend fun generateOffer(request: GenerateOfferRequest) = apiResponseCallback(retrofitService().generateOffer(request)) @@ -40,11 +39,9 @@ class LoanDetailsRepository : ResponseCallback() { suspend fun fetchFeeDetails(request: LoanFeeDetailsRequest) = apiResponseCallback(retrofitService().fetchFeeDetails(request)) - suspend fun offerGenerateStatus() = - apiResponseCallback(retrofitService().offerGenerateStatus()) + suspend fun offerGenerateStatus() = apiResponseCallback(retrofitService().offerGenerateStatus()) - suspend fun offerRejected() = - apiResponseCallback(retrofitService().offerRejected()) + suspend fun offerRejected() = apiResponseCallback(retrofitService().offerRejected()) suspend fun fetchLoanSummary(loanApplicationId: String) = apiResponseCallback(retrofitService().fetchLoanSummary(loanApplicationId)) @@ -61,7 +58,6 @@ class LoanDetailsRepository : ResponseCallback() { suspend fun fetchEmiDetails(loanFeeDetailsRequest: LoanFeeDetailsRequest) = apiResponseCallback(retrofitService().fetchEmiDetails(loanFeeDetailsRequest)) - suspend fun fetchLoanDetails(offerId: String) = apiResponseCallback(retrofitService().fetchLoanDetails(offerId)) diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanOfferUpgradeRepository.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanOfferUpgradeRepository.kt index b2bcc1fdf9..9c0b28ce4c 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanOfferUpgradeRepository.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/repositories/LoanOfferUpgradeRepository.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloan.getloan.loandetails.repositories import com.naviapp.network.retrofit.ResponseCallback @@ -7,4 +14,4 @@ class LoanOfferUpgradeRepository : ResponseCallback() { suspend fun fetchOfferUpgradeDetails(queryMap: HashMap) = apiResponseCallback(retrofitService().fetchOfferUpgradeDetails(queryMap)) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/viewmodels/EffectiveInterestCostVM.kt b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/viewmodels/EffectiveInterestCostVM.kt index c95edfc4fa..731103da10 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/viewmodels/EffectiveInterestCostVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/loandetails/viewmodels/EffectiveInterestCostVM.kt @@ -14,13 +14,13 @@ import com.navi.common.viewmodel.BaseVM import com.naviapp.models.response.EffectiveInterestInfoResponse import com.naviapp.personalloan.getloan.loandetails.repositories.EffectiveInterestCostRepository import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.launch import javax.inject.Inject +import kotlinx.coroutines.launch @HiltViewModel -class EffectiveInterestCostVM @Inject constructor( - private val repository: EffectiveInterestCostRepository -) : BaseVM() { +class EffectiveInterestCostVM +@Inject +constructor(private val repository: EffectiveInterestCostRepository) : BaseVM() { private val _effectiveInterestInfo = MutableLiveData() val effectiveInterestInfo: LiveData @@ -36,4 +36,4 @@ class EffectiveInterestCostVM @Inject constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/summary/adapters/SummaryLineItemsAdapter.kt b/app/src/main/java/com/naviapp/personalloan/getloan/summary/adapters/SummaryLineItemsAdapter.kt index 58e4cb4809..757a23e40a 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/summary/adapters/SummaryLineItemsAdapter.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/summary/adapters/SummaryLineItemsAdapter.kt @@ -16,6 +16,7 @@ import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import com.navi.base.model.LineItem import com.navi.common.utils.log +import com.navi.common.utils.makePartOfTextBold import com.navi.naviwidgets.utils.NaviWidgetIconUtils import com.naviapp.R import com.naviapp.common.listeners.LineItemListener @@ -23,7 +24,6 @@ import com.naviapp.databinding.SummaryLineItemBinding import com.naviapp.models.TextStyle import com.naviapp.personalloan.getloan.loandetails.fragments.LoanDetailsFragment import com.naviapp.utils.isValidIndex -import com.naviapp.utils.makePartOfTextBold import com.naviapp.utils.setTextColorFromString import com.naviapp.utils.spannableString @@ -36,9 +36,7 @@ class SummaryLineItemsAdapter( private val lineItemListener: LineItemListener? = null, private val lineItemSize: Float? = null, private val lastValueTypeFace: Typeface? = null -) : - - RecyclerView.Adapter() { +) : RecyclerView.Adapter() { private lateinit var binding: SummaryLineItemBinding fun setData(lineItemsTemp: List) { @@ -71,21 +69,15 @@ class SummaryLineItemsAdapter( unStrikedTextStyle, lineItem.styledValue ) - textStyle?.textSize?.let { - binding.keyTv.textSize = it - } - textStyle?.textColor?.let { - binding.keyTv.setTextColor(it) - } + textStyle?.textSize?.let { binding.keyTv.textSize = it } + textStyle?.textColor?.let { binding.keyTv.setTextColor(it) } if (boldLastValue == true && position == lineItems.size - 1) { binding.keyTv.typeface = Typeface.DEFAULT_BOLD } if (lastValueTypeFace != null && position == lineItems.size - 1) { binding.keyTv.typeface = lastValueTypeFace } - lineItemSize?.let { - binding.keyTv.textSize = it - } + lineItemSize?.let { binding.keyTv.textSize = it } lineItem.subtitle?.let { handleSpannableView( binding.keyTv, @@ -95,10 +87,11 @@ class SummaryLineItemsAdapter( } binding.iconIv.visibility = View.GONE lineItem.iconCode?.let { - LoanDetailsFragment().onEffectiveInterestCostIconView( - "repayment_details", - lineItem.key?.plus(" @".plus(lineItem.value)) - ) + LoanDetailsFragment() + .onEffectiveInterestCostIconView( + "repayment_details", + lineItem.key?.plus(" @".plus(lineItem.value)) + ) binding.iconIv.visibility = View.VISIBLE binding.iconIv.setImageResource(NaviWidgetIconUtils.getIconResourceId(it)) lineItem.iconCta?.let { ctaData -> @@ -115,10 +108,7 @@ class SummaryLineItemsAdapter( binding.keyIv.visibility = View.VISIBLE binding.keyView.setOnClickListener { binding.keyIv.animate().rotationBy(360f) - lineItemListener?.onLineItemTap( - lineItem.key, - lineItem.dropDown - ) + lineItemListener?.onLineItemTap(lineItem.key, lineItem.dropDown) } } @@ -126,24 +116,16 @@ class SummaryLineItemsAdapter( binding.styledSubvalueTv.visibility = View.VISIBLE binding.styledSubvalueTv.text = it.text it.bold?.let { boldText -> - it.text?.let { text -> - binding.styledSubvalueTv.makePartOfTextBold( - text, boldText - ) - } + it.text?.let { text -> binding.styledSubvalueTv.makePartOfTextBold(text, boldText) } } it.hexColorCode.let { colorString -> binding.styledSubvalueTv.setTextColorFromString(colorString) } - } ?: run { - binding.styledSubvalueTv.visibility = View.GONE } + ?: run { binding.styledSubvalueTv.visibility = View.GONE } - lineItem.styledSubTitle?.let { - binding.styledSubtitleRl.visibility = View.VISIBLE - } ?: run { - binding.styledSubtitleRl.visibility = View.GONE - } + lineItem.styledSubTitle?.let { binding.styledSubtitleRl.visibility = View.VISIBLE } + ?: run { binding.styledSubtitleRl.visibility = View.GONE } } private fun handleSpannableView(tv: TextView, title: String, start: Int) { @@ -156,4 +138,4 @@ class SummaryLineItemsAdapter( class SummaryLineItemsVH(val binding: SummaryLineItemBinding) : RecyclerView.ViewHolder(binding.root) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/getloan/viewmodels/DisbursementVM.kt b/app/src/main/java/com/naviapp/personalloan/getloan/viewmodels/DisbursementVM.kt index 976df2e1c7..72f4175384 100644 --- a/app/src/main/java/com/naviapp/personalloan/getloan/viewmodels/DisbursementVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/getloan/viewmodels/DisbursementVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -29,12 +29,14 @@ class LoanDisbursementVM : BaseVM() { private val _dataAsyncResponse = MutableLiveData>() - val dataAsyncResponse: LiveData> + val dataAsyncResponse: + LiveData> get() = _dataAsyncResponse private val _loanDisbursementResponse = MutableLiveData>() - val loanDisbursementResponse: LiveData> + val loanDisbursementResponse: + LiveData> get() = _loanDisbursementResponse private val _loanBasicDetails = MutableLiveData() @@ -117,4 +119,4 @@ class LoanDisbursementVM : BaseVM() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/intermediate/activity/IntermediateActivity.kt b/app/src/main/java/com/naviapp/personalloan/intermediate/activity/IntermediateActivity.kt index c66d19145f..6ac0da5882 100644 --- a/app/src/main/java/com/naviapp/personalloan/intermediate/activity/IntermediateActivity.kt +++ b/app/src/main/java/com/naviapp/personalloan/intermediate/activity/IntermediateActivity.kt @@ -47,15 +47,13 @@ import com.naviapp.utils.Constants import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class IntermediateActivity : BaseActivity(), View.OnClickListener, - FragmentInterchangeListener, HeaderInteractionListener { +class IntermediateActivity : + BaseActivity(), View.OnClickListener, FragmentInterchangeListener, HeaderInteractionListener { private lateinit var binding: ActivityIntermediateVerificationBinding private val sharedAggregatorVM: AggregatorSharedVM by lazy { - ViewModelProvider(this).get( - AggregatorSharedVM::class.java - ) + ViewModelProvider(this).get(AggregatorSharedVM::class.java) } override fun onCreate(savedInstanceState: Bundle?) { @@ -73,9 +71,8 @@ class IntermediateActivity : BaseActivity(), View.OnClickListener, override fun navigateToNextScreen(currentScreenTag: String, bundle: Bundle) { val fragment = - supportFragmentManager.findFragmentByTag(currentScreenTag) ?: getFragment( - currentScreenTag, bundle - ) + supportFragmentManager.findFragmentByTag(currentScreenTag) + ?: getFragment(currentScreenTag, bundle) val fragmentTransaction = supportFragmentManager.beginTransaction() if (!supportFragmentManager.isStateSaved && !supportFragmentManager.isDestroyed) { fragmentTransaction.replace( @@ -94,18 +91,12 @@ class IntermediateActivity : BaseActivity(), View.OnClickListener, private fun getFragment(screen: String, bundle: Bundle): Fragment { return when (screen) { - SubPageStatusType.MONEY_DISBURSEMENT_STATUS -> DelayedDisbursementFragment.newInstance( - bundle - ) - SubPageStatusType.BANK_STATEMENT_VERIFICATION -> BankStatementFragment.newInstance( - bundle - ) - SubPageStatusType.ACCOUNT_AGGREGATOR -> AccountAggregatorFragment.newInstance( - bundle - ) - SubPageStatusType.BANNER -> FullImageBannerFragment.newInstance( - bundle - ) + SubPageStatusType.MONEY_DISBURSEMENT_STATUS -> + DelayedDisbursementFragment.newInstance(bundle) + SubPageStatusType.BANK_STATEMENT_VERIFICATION -> + BankStatementFragment.newInstance(bundle) + SubPageStatusType.ACCOUNT_AGGREGATOR -> AccountAggregatorFragment.newInstance(bundle) + SubPageStatusType.BANNER -> FullImageBannerFragment.newInstance(bundle) SubPageStatusType.COUPON -> CouponFragment() SubPageStatusType.CREDIT_ANALYSIS -> CreditAnalysisFragment.newInstance() SubPageStatusType.TOP_UP_INTRO -> TopUpLoanIntroFragment.newInstance(bundle) @@ -115,9 +106,8 @@ class IntermediateActivity : BaseActivity(), View.OnClickListener, SubPageStatusType.GST_VERIFICATION -> GstVerificationFragment.getInstance() SubPageStatusType.INCOME_INFO -> MfiInfoFragment.newInstance() SubPageStatusType.EMI_SELECTOR -> EmiSelectorFragment.newInstance(bundle) - SubPageStatusType.EFFECTIVE_INTEREST_COST -> EffectiveInterestCostFragment.newInstance( - bundle - ) + SubPageStatusType.EFFECTIVE_INTEREST_COST -> + EffectiveInterestCostFragment.newInstance(bundle) SubPageStatusType.UPCOMING_EMI_DETAILS -> UpcomingEmiDetailsFragment.newInstance(bundle) else -> BankStatementFragment.newInstance(bundle) } @@ -185,4 +175,4 @@ class IntermediateActivity : BaseActivity(), View.OnClickListener, companion object { const val KEY_NEEDS_RESULT = "KEY_NEEDS_RESULT" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/repository/BankStatementRepository.kt b/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/repository/BankStatementRepository.kt index a0d58ab220..df98dad4b1 100644 --- a/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/repository/BankStatementRepository.kt +++ b/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/repository/BankStatementRepository.kt @@ -1,13 +1,12 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ package com.naviapp.personalloan.intermediate.bankstatement.repository -import com.navi.insurance.models.request.FlowType import com.naviapp.models.request.DigitapRequest import com.naviapp.network.retrofit.ResponseCallback import com.naviapp.utils.retrofitService @@ -31,5 +30,4 @@ class BankStatementRepository : ResponseCallback() { suspend fun fetchBankStatementFaqs() = apiResponseCallback(superAppRetrofitService().fetchFaqs()) - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/viewmodel/BankStatementVM.kt b/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/viewmodel/BankStatementVM.kt index ff52e41f77..76a1df826f 100644 --- a/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/viewmodel/BankStatementVM.kt +++ b/app/src/main/java/com/naviapp/personalloan/intermediate/bankstatement/viewmodel/BankStatementVM.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -11,8 +11,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.navi.common.model.UploadDataAsyncResponse import com.navi.common.viewmodel.BaseVM -import com.navi.insurance.models.request.FlowType -import com.naviapp.models.PageStatusType.OFFER_GENERATION import com.naviapp.models.request.DigitapRequest import com.naviapp.models.response.* import com.naviapp.personalloan.getloan.bankdetails.viewmodels.AggregatorSharedVM @@ -20,8 +18,9 @@ import com.naviapp.personalloan.intermediate.bankstatement.repository.BankStatem import com.naviapp.utils.Constants import kotlinx.coroutines.launch -class BankStatementVM(private val bankStatementRepository: BankStatementRepository = BankStatementRepository()) : - BaseVM() { +class BankStatementVM( + private val bankStatementRepository: BankStatementRepository = BankStatementRepository() +) : BaseVM() { private val _bankStatementData = MutableLiveData() val bankStatementData: LiveData @@ -51,7 +50,6 @@ class BankStatementVM(private val bankStatementRepository: BankStatementReposito val errorAsyncResponse: LiveData get() = _errorAsyncResponse - fun fetchBankStatementData(flowType: String = Constants.EMPTY) { coroutineScope.launch { val response = bankStatementRepository.fetchBankStatementData(flowType) @@ -88,8 +86,7 @@ class BankStatementVM(private val bankStatementRepository: BankStatementReposito fun fetchBankStatementStatus(digitapRequest: DigitapRequest) { coroutineScope.launch { - val response = - bankStatementRepository.fetchBankStatementStatus(digitapRequest) + val response = bankStatementRepository.fetchBankStatementStatus(digitapRequest) if (response.error == null) { _bankStatementStatus.value = response.data } else { @@ -106,7 +103,8 @@ class BankStatementVM(private val bankStatementRepository: BankStatementReposito when (response.errors?.first()?.code) { AggregatorSharedVM.ErrorType.BANK_STATEMENT_NAME_MIS_MATCH.name, AggregatorSharedVM.ErrorType.BANK_STATEMENT_PAN_MIS_MATCH.name, - AggregatorSharedVM.ErrorType.BANK_STATEMENT_ACCOUNT_NUMBER_ALREADY_PRESENT.name -> { + AggregatorSharedVM.ErrorType.BANK_STATEMENT_ACCOUNT_NUMBER_ALREADY_PRESENT + .name -> { setErrorData(response.errors, response.error, cancelable = false) } AggregatorSharedVM.ErrorType.BANK_STATEMENT_SOFT_REJECT.name -> { @@ -140,4 +138,4 @@ class BankStatementVM(private val bankStatementRepository: BankStatementReposito } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloan/intermediate/topup/fragment/TopUpLoanIntroFragment.kt b/app/src/main/java/com/naviapp/personalloan/intermediate/topup/fragment/TopUpLoanIntroFragment.kt index 3e88188103..e178405682 100644 --- a/app/src/main/java/com/naviapp/personalloan/intermediate/topup/fragment/TopUpLoanIntroFragment.kt +++ b/app/src/main/java/com/naviapp/personalloan/intermediate/topup/fragment/TopUpLoanIntroFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -14,8 +14,9 @@ import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.CtaData -import com.naviapp.analytics.utils.NaviAnalytics import com.navi.common.ui.fragment.BaseFragment +import com.navi.common.utils.observeNullable +import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.listeners.FooterInteractionListener import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.FragmentTopUpIntroBinding @@ -25,7 +26,6 @@ import com.naviapp.utils.IntentConstants.OFFER_REFERENCE_ID import com.naviapp.utils.IntentConstants.OFFER_TYPE_ON_DEMAND import com.naviapp.utils.IntentConstants.ON_DEMAND_TOP_UP_OFFER_BALANCE import com.naviapp.utils.IntentConstants.ON_DEMAND_TOP_UP_OFFER_TYPE -import com.navi.common.utils.observeNullable class TopUpLoanIntroFragment : BaseFragment(), FooterInteractionListener { private lateinit var binding: FragmentTopUpIntroBinding @@ -66,7 +66,6 @@ class TopUpLoanIntroFragment : BaseFragment(), FooterInteractionListener { viewModel.fetchTopUpLoanInfo(this) } } - } private fun initObservers() { @@ -98,17 +97,13 @@ class TopUpLoanIntroFragment : BaseFragment(), FooterInteractionListener { } else { naviAnalyticsEventTracker.onNextClicked() } - val bundle = Bundle().apply { - putString(LOAN_OFFER_TYPE, loanOfferType) - } + val bundle = Bundle().apply { putString(LOAN_OFFER_TYPE, loanOfferType) } ctaData?.let { NaviDeepLinkNavigator.navigate(activity, it, true, bundle = bundle) } } companion object { fun newInstance(bundle: Bundle): TopUpLoanIntroFragment { - return TopUpLoanIntroFragment().apply { - arguments = bundle - } + return TopUpLoanIntroFragment().apply { arguments = bundle } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/addressverificationrevamp/fragment/KycAddressProofV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/addressverificationrevamp/fragment/KycAddressProofV2Fragment.kt index 619d420508..bc0340ebe7 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/addressverificationrevamp/fragment/KycAddressProofV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/addressverificationrevamp/fragment/KycAddressProofV2Fragment.kt @@ -43,8 +43,12 @@ import com.naviapp.personalloanrevamp.kyc.listener.UpdateKycStateListener import com.naviapp.utils.Constants import com.naviapp.utils.toast -class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, - DocumentUploadListener, FooterViewV2.FooterInteractionListener, CurrentAddressChangeListener { +class KycAddressProofV2Fragment : + BaseFragment(), + View.OnClickListener, + DocumentUploadListener, + FooterViewV2.FooterInteractionListener, + CurrentAddressChangeListener { private lateinit var binding: FragmentKycAddressProofV2Binding private val viewModel by lazy { ViewModelProvider(this).get(AddressVerificationVM::class.java) } @@ -128,11 +132,7 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, viewModel.kycAddressDetailsSubmitAsyncData.observeNonNull(viewLifecycleOwner) { data -> data.requestId?.let { requestId -> firebaseRequestId = requestId - firebaseInit( - requestId, - UPDATE_KYC_DETAILS, - data.notificationPath.orEmpty() - ) + firebaseInit(requestId, UPDATE_KYC_DETAILS, data.notificationPath.orEmpty()) apiPollInit(requestId, UPDATE_KYC_DETAILS) } } @@ -165,7 +165,9 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, KycUiStatusValue.SOFT_REJECT.name -> { kycListener?.onKycFailure() } - KycUiStatusValue.IN_REVIEW.name, KycUiStatusValue.OSV_VERIFICATION_IN_PROGRESS.name, KycUiStatusValue.OSV_OPS_VERIFICATION_PENDING.name -> { + KycUiStatusValue.IN_REVIEW.name, + KycUiStatusValue.OSV_VERIFICATION_IN_PROGRESS.name, + KycUiStatusValue.OSV_OPS_VERIFICATION_PENDING.name -> { navigateToKycInReviewScreen() } else -> { @@ -192,10 +194,7 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, ) } - binding.footerView.setProperties( - addressProofResponse?.footer, - this - ) + binding.footerView.setProperties(addressProofResponse?.footer, this) addressProofResponse?.content?.let { currentAddress -> currentAddress.documentType?.let { type -> @@ -240,28 +239,37 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, } private fun navigateToKycInReviewScreen() { - listener?.navigateTo(GetLoanV2ViewHelper.KYC_IN_REVIEW, - bundle = Bundle().apply { - putString( - InReviewV2Fragment.TITLE, - resources.getString(R.string.kyc_verification_pending) - ) - putString( - InReviewV2Fragment.DESCRIPTION, - resources.getString(R.string.kyc_pending_description) - ) - }) + listener?.navigateTo( + GetLoanV2ViewHelper.KYC_IN_REVIEW, + bundle = + Bundle().apply { + putString( + InReviewV2Fragment.TITLE, + resources.getString(R.string.kyc_verification_pending) + ) + putString( + InReviewV2Fragment.DESCRIPTION, + resources.getString(R.string.kyc_pending_description) + ) + } + ) } private fun navigateToNextScreen() { viewModel.kycStatus.value?.footer?.nextCta?.url?.let { val loanApplicationId = - viewModel.kycStatus.value?.footer?.nextCta?.parameters?.firstOrNull { item -> - item.key == Constants.PERSONAL_LOAN_APPLICATION_ID - }?.value - listener?.navigateTo(it, Bundle().apply { - putString(Constants.PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) - }) + viewModel.kycStatus.value + ?.footer + ?.nextCta + ?.parameters + ?.firstOrNull { item -> item.key == Constants.PERSONAL_LOAN_APPLICATION_ID } + ?.value + listener?.navigateTo( + it, + Bundle().apply { + putString(Constants.PERSONAL_LOAN_APPLICATION_ID, loanApplicationId) + } + ) } } @@ -277,9 +285,12 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, } fun getLoanApplicationId(): String? { - return viewModel.kycStatus.value?.footer?.nextCta?.parameters?.firstOrNull { item -> - item.key == Constants.PERSONAL_LOAN_APPLICATION_ID - }?.value + return viewModel.kycStatus.value + ?.footer + ?.nextCta + ?.parameters + ?.firstOrNull { item -> item.key == Constants.PERSONAL_LOAN_APPLICATION_ID } + ?.value } private fun initListeners() { @@ -288,17 +299,17 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, override fun onClick(p0: View?) { when (view?.id) { - R.id.address_thum_container, R.id.edit_document_tv -> openDocumentUploadScreen() + R.id.address_thum_container, + R.id.edit_document_tv -> openDocumentUploadScreen() R.id.back_iv -> onBackButtonClick() - R.id.current_address_pincode -> activity?.toast(getString(R.string.address_pincode_message)) + R.id.current_address_pincode -> + activity?.toast(getString(R.string.address_pincode_message)) R.id.current_address_city -> activity?.toast(getString(R.string.address_city_message)) } } override fun onFooterBackPressed(backCta: CtaData?) { - backCta?.url?.let { - listener?.navigateTo(it) - } + backCta?.url?.let { listener?.navigateTo(it) } } override fun onFooterNextPressed(nextCta: CtaData?) { @@ -311,7 +322,6 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, } locationUpdateListener?.updateLocation(Constants.PL_KYC_LOCATION) - } override fun onDocumentUploadFinished(documentType: String, url: String) { @@ -341,16 +351,17 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, } // API Polling - private val pollingTimeoutClickListener: View.OnClickListener = View.OnClickListener { - when (errorTag) { - ApiErrorTagType.KYC_DETAIL_UPLOAD -> { - viewModel.addressProofLiveData.value?.content?.let { currentAddress -> - viewModel.submitKycDetails(currentAddress) - locationUpdateListener?.updateLocation(Constants.PL_KYC_LOCATION) + private val pollingTimeoutClickListener: View.OnClickListener = + View.OnClickListener { + when (errorTag) { + ApiErrorTagType.KYC_DETAIL_UPLOAD -> { + viewModel.addressProofLiveData.value?.content?.let { currentAddress -> + viewModel.submitKycDetails(currentAddress) + locationUpdateListener?.updateLocation(Constants.PL_KYC_LOCATION) + } } } } - } private fun handleTimeOutError(errorTag: String) { showTimeoutErrorScreen( @@ -364,28 +375,28 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, } private var errorTag: String? = null - private val onPollingEnd = { - handleTimeOutError(errorTag.orEmpty()) - } + private val onPollingEnd = { handleTimeOutError(errorTag.orEmpty()) } private fun apiPollInit(requestId: String, type: String) { errorTag = ApiErrorTagType.KYC_DETAIL_UPLOAD - apiPollScheduler = ApiPollScheduler(doOnTimeout = onPollingEnd) { - viewModel.checkApiPollStatus(requestId, type) - } + apiPollScheduler = + ApiPollScheduler(doOnTimeout = onPollingEnd) { + viewModel.checkApiPollStatus(requestId, type) + } apiPollScheduler?.scheduleApiPoll() } // Firebase private fun firebaseInit(requestId: String, type: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - apiPollScheduler?.stopApiPoll() - handleFirebaseResult(it.status.orEmpty(), type, false) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { + apiPollScheduler?.stopApiPoll() + handleFirebaseResult(it.status.orEmpty(), type, false) + } } } - } firebaseDataHelper = null firebaseDataHelper = FirebaseDataHelper() firebaseDataHelper?.initFirebaseDataReceiver( @@ -397,17 +408,11 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, ) } + private fun handleFirebaseResult(status: String, type: String, isPolling: Boolean = true) { - private fun handleFirebaseResult( - status: String, - type: String, - isPolling: Boolean = true - ) { - - if (TextUtils.equals(status, FirebaseStatusType.SUCCESS) - || TextUtils.equals( - status, FirebaseStatusType.FAILURE - ) + if ( + TextUtils.equals(status, FirebaseStatusType.SUCCESS) || + TextUtils.equals(status, FirebaseStatusType.FAILURE) ) { deInitializeFirebaseListener() apiPollScheduler?.stopApiPoll() @@ -460,4 +465,4 @@ class KycAddressProofV2Fragment : BaseFragment(), View.OnClickListener, interface CurrentAddressChangeListener { fun onCurrentAddressChanged(address: CurrentAddress, position: Int) fun onUploadNowClicked(address: CurrentAddress, position: Int) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/BankStatementVerificationMethodView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/BankStatementVerificationMethodView.kt index b86d0f78b1..57dc813195 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/BankStatementVerificationMethodView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/BankStatementVerificationMethodView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.common.customview import android.content.Context @@ -20,35 +27,32 @@ import com.naviapp.utils.IconUtils class BankStatementVerificationMethodView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) { - private val binding = BankStatementVerificationMethodLayoutBinding.inflate( - LayoutInflater.from(context), this, true - ) + private val binding = + BankStatementVerificationMethodLayoutBinding.inflate( + LayoutInflater.from(context), + this, + true + ) init { - layoutParams = LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT - ) + layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) } fun setProperties( method: SelectorMethodData, callback: ((selectedValue: BankStatementV2Fragment.SelectedOption) -> Unit)? = null, - infoClickListener: (infoData : InfoCtaData?) -> Unit + infoClickListener: (infoData: InfoCtaData?) -> Unit ) { setCardWidth() method.netBankingMethod?.apply { setNormalDrawable(binding.otpOption.rootItem) binding.netBankingOption.badgeTv.isVisible = recommendedTitle.isNotNullAndNotEmpty() binding.netBankingOption.badgeTv.text = recommendedTitle - iconCode?.let { - IconUtils.updateIcon(iconCode, binding.netBankingOption.iconImv) - } + iconCode?.let { IconUtils.updateIcon(iconCode, binding.netBankingOption.iconImv) } binding.netBankingOption.titleTv.text = title binding.netBankingOption.subtitleTv.text = subTitle binding.netBankingOption.infoImv.isVisible = infoCta?.iconCode.isNotNullAndNotEmpty() - infoCta?.iconCode?.let { - IconUtils.updateIcon(it, binding.netBankingOption.infoImv) - } + infoCta?.iconCode?.let { IconUtils.updateIcon(it, binding.netBankingOption.infoImv) } binding.netBankingOption.infoImv.setOnClickListener { infoClickListener.invoke(infoCtaData) } @@ -57,25 +61,18 @@ class BankStatementVerificationMethodView(context: Context, attrs: AttributeSet? setNormalDrawable(binding.otpOption.rootItem) setSelectedDrawable(binding.netBankingOption.rootItem) } - } method.otpMethod?.apply { setNormalDrawable(binding.netBankingOption.rootItem) binding.otpOption.badgeTv.isVisible = recommendedTitle.isNotNullAndNotEmpty() binding.otpOption.badgeTv.text = recommendedTitle - iconCode?.let { - IconUtils.updateIcon(iconCode, binding.otpOption.iconImv) - } + iconCode?.let { IconUtils.updateIcon(iconCode, binding.otpOption.iconImv) } binding.otpOption.titleTv.text = title binding.otpOption.subtitleTv.text = subTitle binding.otpOption.infoImv.isVisible = infoCta?.iconCode.isNotNullAndNotEmpty() - infoCta?.iconCode?.let { - IconUtils.updateIcon(it, binding.otpOption.infoImv) - } - binding.otpOption.infoImv.setOnClickListener { - infoClickListener.invoke(infoCtaData) - } + infoCta?.iconCode?.let { IconUtils.updateIcon(it, binding.otpOption.infoImv) } + binding.otpOption.infoImv.setOnClickListener { infoClickListener.invoke(infoCtaData) } binding.otpOption.rootItem.setOnClickListener { callback?.invoke(BankStatementV2Fragment.SelectedOption.ACCOUNT_AGGREGATOR) setNormalDrawable(binding.netBankingOption.rootItem) @@ -85,19 +82,21 @@ class BankStatementVerificationMethodView(context: Context, attrs: AttributeSet? } private fun setNormalDrawable(view: View) { - view.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_12).toInt(), - strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), - strokeColor = ResourcesCompat.getColor(resources, R.color.divider_gray, null) - ) + view.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_12).toInt(), + strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), + strokeColor = ResourcesCompat.getColor(resources, R.color.divider_gray, null) + ) } private fun setSelectedDrawable(view: View) { - view.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_12).toInt(), - strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), - strokeColor = ResourcesCompat.getColor(resources, R.color.outrageous_orange, null) - ) + view.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_12).toInt(), + strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), + strokeColor = ResourcesCompat.getColor(resources, R.color.outrageous_orange, null) + ) } private fun setCardWidth() { @@ -108,12 +107,8 @@ class BankStatementVerificationMethodView(context: Context, attrs: AttributeSet? lp?.width = cardWidth.toInt() binding.netBankingOption.rootItem.layoutParams = lp - lp = binding.otpOption.rootItem.layoutParams as? LinearLayout.LayoutParams lp?.width = cardWidth.toInt() binding.otpOption.rootItem.layoutParams = lp - } - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/InfoBottomSheetV2.kt b/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/InfoBottomSheetV2.kt index 9ea51a2039..b72ea10bd6 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/InfoBottomSheetV2.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/common/customview/InfoBottomSheetV2.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.common.customview import android.graphics.PorterDuff @@ -21,7 +28,7 @@ class InfoBottomSheetV2() : BaseBottomSheet() { private lateinit var binding: InfoBottomSheetV2Binding - val ctaClickListener = MutableLiveData(false) + val ctaClickListener = MutableLiveData(false) override fun setContainerView(viewStub: ViewStub) { viewStub.layoutResource = R.layout.info_bottom_sheet_v2 @@ -30,10 +37,12 @@ class InfoBottomSheetV2() : BaseBottomSheet() { } private fun initUI() { - binding.ctaBtn.background = getNaviDrawable( - backgroundColor = ResourcesCompat.getColor(resources, R.color.outrageous_orange, null), - cornerRadius = resources.getDimension(R.dimen.layout_dp_32).toInt() - ) + binding.ctaBtn.background = + getNaviDrawable( + backgroundColor = + ResourcesCompat.getColor(resources, R.color.outrageous_orange, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_32).toInt() + ) arguments?.getString(ICON_CODE)?.let { IconUtils.updateIcon(it, binding.headerIcon) binding.headerIcon.setColorFilter( @@ -41,7 +50,8 @@ class InfoBottomSheetV2() : BaseBottomSheet() { resources, arguments?.getInt(ICON_TINT) ?: R.color.black, null - ), PorterDuff.Mode.SRC_IN + ), + PorterDuff.Mode.SRC_IN ) } @@ -57,16 +67,13 @@ class InfoBottomSheetV2() : BaseBottomSheet() { } safelyDismissDialog() } - } ?: run { - binding.ctaBtn.isVisible = false } + ?: run { binding.ctaBtn.isVisible = false } } override val screenName: String get() = NaviAnalytics.INFO_BOTTOM_SHEET_V2 - - companion object { const val TAG = "InfoBottomSheetV2" @@ -86,16 +93,16 @@ class InfoBottomSheetV2() : BaseBottomSheet() { ctaData: CtaData? = null ): InfoBottomSheetV2 { return InfoBottomSheetV2().apply { - arguments = Bundle().apply { - putString(ICON_CODE, iconCode) - putInt(ICON_TINT, iconTint ?: R.color.black) - putString(HEADER, header) - putString(SUB_HEADER, subHeader) - putString(DESCRIPTION, description) - putParcelable(CTA_DATA, ctaData) - } + arguments = + Bundle().apply { + putString(ICON_CODE, iconCode) + putInt(ICON_TINT, iconTint ?: R.color.black) + putString(HEADER, header) + putString(SUB_HEADER, subHeader) + putString(DESCRIPTION, description) + putParcelable(CTA_DATA, ctaData) + } } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/customview/LoanOfferStickinessBottomSheetV2.kt b/app/src/main/java/com/naviapp/personalloanrevamp/customview/LoanOfferStickinessBottomSheetV2.kt index 4c91588a0e..8453308a46 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/customview/LoanOfferStickinessBottomSheetV2.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/customview/LoanOfferStickinessBottomSheetV2.kt @@ -18,7 +18,6 @@ import com.naviapp.models.response.LoanOfferBottomSheetData class LoanOfferStickinessBottomSheetV2 : BaseBottomSheet() { private lateinit var binding: LoanOfferStickinessBottomSheetBinding - private val naviAnalyticsEventTrackerForLoanSticky = NaviAnalytics.naviAnalytics.loanOfferStickinessEvent() diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/error/aactivity/ErrorScreenV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/error/aactivity/ErrorScreenV2Activity.kt index be8477e5e1..d893c545cb 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/error/aactivity/ErrorScreenV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/error/aactivity/ErrorScreenV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.error.aactivity import android.content.Intent @@ -52,7 +59,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener private var isKycRejection = false private val viewModel by lazy { ViewModelProvider(this).get(ErrorVM::class.java) } - private val activeLoanDetailsVM by lazy { ViewModelProvider(this).get(ActiveLoanDetailsVM::class.java) } + private val activeLoanDetailsVM by lazy { + ViewModelProvider(this).get(ActiveLoanDetailsVM::class.java) + } private val analyticsEventTracker = NaviAnalytics.naviAnalytics.RatingDetail() private val helpEventTracker by lazy { NaviAnalytics.naviAnalytics.Faq() } @@ -72,7 +81,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener showLoader() if (isSecondLoanJourney || isSoftReject || isUwRejection || isKycRejection) { val rejectionData = - intent.getParcelableExtra(ErrorActivity.REJECTION_DATA) + intent.getParcelableExtra( + ErrorActivity.REJECTION_DATA + ) if (rejectionData == null) { viewModel.fetchRejectionDetailsV2() } else { @@ -94,15 +105,14 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener errorData = savedInstanceState.getParcelable(ErrorActivity.ERROR_DATA) redirectStatusData = savedInstanceState.getParcelable(ErrorActivity.REDIRECT_DATA) } - isSecondLoanJourney = intent.getBooleanExtra(GetLoanActivity.IS_FOR_SECOND_LOAN_JOURNEY, false) + isSecondLoanJourney = + intent.getBooleanExtra(GetLoanActivity.IS_FOR_SECOND_LOAN_JOURNEY, false) isSoftReject = intent.getStringExtra(ErrorActivity.IS_SOFT_REJECT) == Constants.TRUE - isHomeLoan = intent.getBooleanExtra(ErrorActivity.IS_HOME_LOAN, false) - .orFalse() || intent.getStringExtra( - ErrorActivity.IS_HOME_LOAN - ) == Constants.TRUE + isHomeLoan = + intent.getBooleanExtra(ErrorActivity.IS_HOME_LOAN, false).orFalse() || + intent.getStringExtra(ErrorActivity.IS_HOME_LOAN) == Constants.TRUE isUwRejection = intent.getBooleanExtra(IS_UW_REJECTION, false) - isKycRejection = intent.getBooleanExtra(IS_KYC_REJECTION,false) - + isKycRejection = intent.getBooleanExtra(IS_KYC_REJECTION, false) } private fun initObservers() { @@ -130,9 +140,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener ) binding.primaryAction.setOnClickListener { NaviDeepLinkNavigator.navigate( - this, CtaData( - url = error.content.nextCta.url - ), null + this, + CtaData(url = error.content.nextCta.url), + null ) } } @@ -145,7 +155,8 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener private fun getTag(rejectReason: String?): String { return when (rejectReason) { - ErrorActivity.PROFILE_NOT_ELIGIBLE_DUE_TO_MFI, OFFER_INELIGIBLE -> MFIErrorFragmentV2.TAG + ErrorActivity.PROFILE_NOT_ELIGIBLE_DUE_TO_MFI, + OFFER_INELIGIBLE -> MFIErrorFragmentV2.TAG else -> ErrorV2Fragment.TAG } } @@ -154,15 +165,14 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener val tag = getTag(data.first?.rejectReason) trackSoftRejectEvent(data.first?.rejectReason, data.second?.code) val fragment = - supportFragmentManager.findFragmentByTag(tag) ?: getFragment( - data.first?.rejectReason, - intent.extras - ) + supportFragmentManager.findFragmentByTag(tag) + ?: getFragment(data.first?.rejectReason, intent.extras) val bundle = fragment.arguments ?: Bundle() - fragment.arguments = bundle.apply { - putParcelable(ErrorActivity.ERROR_DATA, data.second) - putBoolean(ErrorActivity.IS_HOME_LOAN, isHomeLoan) - } + fragment.arguments = + bundle.apply { + putParcelable(ErrorActivity.ERROR_DATA, data.second) + putBoolean(ErrorActivity.IS_HOME_LOAN, isHomeLoan) + } supportFragmentManager.beginTransaction().run { replace(R.id.error_container_fl, fragment, tag) commit() @@ -171,15 +181,18 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener private fun getFragment(rejectReason: String?, bundle: Bundle?): Fragment { return when (rejectReason) { - ErrorActivity.PROFILE_NOT_ELIGIBLE_DUE_TO_MFI, OFFER_INELIGIBLE -> MFIErrorFragmentV2() - else -> ErrorV2Fragment().apply { - arguments = Bundle().apply { - putString( - ErrorFragment.ERROR_SCREEN_NAME, - NaviAnalytics.SYSTEM_UNDER_MAINTENANCE_SCREEN - ) + ErrorActivity.PROFILE_NOT_ELIGIBLE_DUE_TO_MFI, + OFFER_INELIGIBLE -> MFIErrorFragmentV2() + else -> + ErrorV2Fragment().apply { + arguments = + Bundle().apply { + putString( + ErrorFragment.ERROR_SCREEN_NAME, + NaviAnalytics.SYSTEM_UNDER_MAINTENANCE_SCREEN + ) + } } - } } } @@ -187,10 +200,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener val tag = getTag(data?.content?.rejectionCode) trackSoftRejectEvent(data?.content?.rejectionCode, data?.content?.rejectionCode) isSoftRejectFromHL = data?.content?.cardsData.isNotNull() - val fragment = supportFragmentManager.findFragmentByTag(tag) ?: getFragment( - data?.content?.rejectionCode, - intent.extras - ) + val fragment = + supportFragmentManager.findFragmentByTag(tag) + ?: getFragment(data?.content?.rejectionCode, intent.extras) val bundle = fragment.arguments ?: Bundle() fragment.arguments = bundle.apply { @@ -204,17 +216,18 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener } private fun trackSoftRejectEvent(rejectReason: String?, code: String?) { - val eventName = when (rejectReason) { - PROFILE_NOT_ELIGIBLE -> NaviAnalytics.PROFILE_SOFT_REJECTED - KYC_FAILED -> NaviAnalytics.KYC_SOFT_REJECTED - OFFER_INELIGIBLE -> NaviAnalytics.OFFER_SOFT_REJECTED - else -> { - when (intent?.extras?.getString(ErrorActivity.ERROR_TYPE)) { - ErrorActivity.APPLICATION_ON_HOLD -> NaviAnalytics.LOAN_RCS_SCREEN - else -> null + val eventName = + when (rejectReason) { + PROFILE_NOT_ELIGIBLE -> NaviAnalytics.PROFILE_SOFT_REJECTED + KYC_FAILED -> NaviAnalytics.KYC_SOFT_REJECTED + OFFER_INELIGIBLE -> NaviAnalytics.OFFER_SOFT_REJECTED + else -> { + when (intent?.extras?.getString(ErrorActivity.ERROR_TYPE)) { + ErrorActivity.APPLICATION_ON_HOLD -> NaviAnalytics.LOAN_RCS_SCREEN + else -> null + } } } - } eventName?.let { NaviTrackEvent.trackEvent(eventName) } code?.let { NaviAnalytics.naviAnalytics.Errors().startScreen(it) } @@ -222,11 +235,12 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener private fun handleRatingUi(isRatingEnabled: Boolean = false) { if (isRatingEnabled) { - val ratingListener = object : RatingChangeListener { - override fun onRatingChange(rating: Float?) { - openRatingScreen(rating) + val ratingListener = + object : RatingChangeListener { + override fun onRatingChange(rating: Float?) { + openRatingScreen(rating) + } } - } binding.ratingViewLay.isVisible = true binding.ratingViewLay.setBackgroundResource(R.drawable.bg_rounded_rect_with_shadow) binding.ratingViewLay.setListener(ratingListener) @@ -239,13 +253,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener private fun openRatingScreen(rating: Float? = null) { analyticsEventTracker.onRatingRejectScreenSelect(rating?.toString().orEmpty()) val b = Bundle() - rating?.apply { - b.putFloat(RatingActivity.RATING_VALUE, this) - } + rating?.apply { b.putFloat(RatingActivity.RATING_VALUE, this) } b.putString(RatingActivity.SCREEN_FROM, RatingActivity.SCREEN_FROM_SOFT_REJECT) - redirectStatusData?.apply { - b.putParcelable(RatingActivity.RATING_DATA, this) - } + redirectStatusData?.apply { b.putParcelable(RatingActivity.RATING_DATA, this) } ScreenNavigator.instance.startActivity( this, ScreenNavigator.RATING_SCREEN, @@ -260,7 +270,9 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { super.onActivityResult(requestCode, resultCode, intent) try { - if (requestCode == RatingActivity.RATING_SCREEN_REQUEST_CODE && resultCode == RESULT_OK) { + if ( + requestCode == RatingActivity.RATING_SCREEN_REQUEST_CODE && resultCode == RESULT_OK + ) { if (isDead()) return val data = intent?.extras?.getBoolean(RatingActivity.IS_RATING_CANCELLED).orTrue() if (data) { @@ -307,7 +319,6 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener moveToDashBoardScreen() } - override val screenName: String get() = NaviAnalytics.ERROR_ACTIVITY_V2 @@ -323,6 +334,4 @@ class ErrorScreenV2Activity : BaseActivity(), NaviHeaderView.InteractionListener const val REJECTION_DATA = "PROFILE_NOT_ELIGIBLE" const val IS_KYC_REJECTION = "IS_KYC_REJECTION" } - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/error/fragments/ErrorV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/error/fragments/ErrorV2Fragment.kt index a52d861412..62bc9ee32c 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/error/fragments/ErrorV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/error/fragments/ErrorV2Fragment.kt @@ -1,7 +1,13 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.error.fragments import android.content.Context -import android.graphics.Color import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -50,17 +56,22 @@ class ErrorV2Fragment : BaseFragment() { colorInt = R.color.white, hideDivider = true ) - binding.daysLayout.rootLayout.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), - gradientOrientation = GradientOrientation.LEFT_RIGHT, - backgroundColor = ResourcesCompat.getColor(resources,R.color.light_pink, null) - ) - binding.actionBtn.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_32).toInt(), - backgroundColor = ResourcesCompat.getColor(resources, R.color.outrageous_orange, null) - ) + binding.daysLayout.rootLayout.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), + gradientOrientation = GradientOrientation.LEFT_RIGHT, + backgroundColor = ResourcesCompat.getColor(resources, R.color.light_pink, null) + ) + binding.actionBtn.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_32).toInt(), + backgroundColor = + ResourcesCompat.getColor(resources, R.color.outrageous_orange, null) + ) - if (arguments?.getParcelable(ErrorActivity.ERROR_DATA) != null) { // in Offer expire case + if ( + arguments?.getParcelable(ErrorActivity.ERROR_DATA) != null + ) { // in Offer expire case arguments?.getParcelable(ErrorActivity.ERROR_DATA)?.run { binding.tvTitle.text = title binding.tvDescription.text = message @@ -77,7 +88,7 @@ class ErrorV2Fragment : BaseFragment() { } } } - } else { // fetching rejection detail from v2 + } else { // fetching rejection detail from v2 val error = arguments?.getParcelable(ErrorScreenV2Activity.REJECTION_DATA) error?.humanReadableContent?.title?.let { binding.tvTitle.text = it } @@ -88,18 +99,16 @@ class ErrorV2Fragment : BaseFragment() { binding.daysLayout.tvTryAgainAfter.text = it.title binding.daysLayout.tvDays.text = it.description binding.daysLayout.tvNoOfDays.text = error.humanReadableContent.numberOfDays - } ?: run { - binding.daysLayout.rootLayout.visibility = View.GONE } + ?: run { binding.daysLayout.rootLayout.visibility = View.GONE } error?.humanReadableContent?.numberOfDays?.let { binding.daysLayout.rootLayout.visibility = View.VISIBLE binding.daysLayout.tvTryAgainAfter.text = resources.getString(R.string.try_again_after) binding.daysLayout.tvDays.text = resources.getString(R.string.days) binding.daysLayout.tvNoOfDays.text = it - } ?: run { - binding.daysLayout.rootLayout.visibility = View.GONE } + ?: run { binding.daysLayout.rootLayout.visibility = View.GONE } binding.actionBtn.text = error?.nextCta?.title ?: getString(R.string.re_submit_application) @@ -118,8 +127,7 @@ class ErrorV2Fragment : BaseFragment() { private fun setIcon(iconType: String?) { binding.ivIcon.setImageResource( - if (iconType == IconUtils.SOFT_REJECT_ICON) R.drawable.ic_soft_reject_icon - else 0 + if (iconType == IconUtils.SOFT_REJECT_ICON) R.drawable.ic_soft_reject_icon else 0 ) } @@ -131,5 +139,4 @@ class ErrorV2Fragment : BaseFragment() { const val ERROR_SCREEN_NAME = "ERROR_SCREEN_NAME_V2" const val ERROR_TYPE = "ERROR_TYPE" } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/BankAccountVerificationLoaderV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/BankAccountVerificationLoaderV2Activity.kt index 1dc7381b43..10489dd763 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/BankAccountVerificationLoaderV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/BankAccountVerificationLoaderV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.activities import android.animation.Animator @@ -41,9 +48,7 @@ import com.naviapp.utils.Constants class BankAccountVerificationLoaderV2Activity : BaseActivity() { private lateinit var binding: ActivityBankAccountVerificationLoaderV2Binding - private val viewModel by lazy { - ViewModelProvider(this).get(BankDetailsVM::class.java) - } + private val viewModel by lazy { ViewModelProvider(this).get(BankDetailsVM::class.java) } private var bankDetail: BankDetail? = null private var timer: CountDownTimer? = null private var apiPollScheduler: ApiPollScheduler? = null @@ -54,7 +59,6 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { private var loanType: String? = null private var journeyType: String? = null - private fun initObservers() { viewModel.uiStatusData.observeNonNull(this) { hideLoader() @@ -95,11 +99,11 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { binding.failedTitleTv.text = resources.getString(R.string.bank_verification_failed) binding.failedSubtitleTv.text = resources.getString(R.string.bank_verification_failed_description) - binding.footerView.binding.footer = Footer( - backCta = CtaData(title = resources.getString(R.string.go_home)), nextCta = CtaData( - title = resources.getString(R.string.retry) + binding.footerView.binding.footer = + Footer( + backCta = CtaData(title = resources.getString(R.string.go_home)), + nextCta = CtaData(title = resources.getString(R.string.retry)) ) - ) binding.footerView.binding.nextBtn.setOnClickListener { naviAnalyticsEventTracker.onPennyDropRetryButtonTap(loanType, journeyType) retryBankAccountVerification() @@ -138,10 +142,7 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { ) super.setContentView(binding.root) NaviTrackEvent.sendScreenTransitionEvent(screenName) - initError( - viewModel, - actionErrorV2Enabled = true - ) + initError(viewModel, actionErrorV2Enabled = true) initUi() initListeners() initAnimation() @@ -161,53 +162,63 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { apiPollInit(it) } } - } ?: run { - setUpRetryBankAccountVerificationScreen() } + ?: run { setUpRetryBankAccountVerificationScreen() } } } private fun navigateToPennyDropFailure() { - Handler().postDelayed({ - if (isDestroyed) return@postDelayed - NaviTrackEvent.setStartTs(screenName) - val resultIntent = Intent() - resultIntent.putExtra(PENNY_DROP_FAILURE, true) - val pennyDropBankData = PennyDropBankData( - bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), - bankIfscName = intent.getStringExtra(Constants.BANK_IFSC), - bankAccountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), - loanApplicationId = intent.getStringExtra(Constants.LOAN_APPLICATION_ID) + Handler() + .postDelayed( + { + if (isDestroyed) return@postDelayed + NaviTrackEvent.setStartTs(screenName) + val resultIntent = Intent() + resultIntent.putExtra(PENNY_DROP_FAILURE, true) + val pennyDropBankData = + PennyDropBankData( + bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), + bankIfscName = intent.getStringExtra(Constants.BANK_IFSC), + bankAccountNumber = + intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), + loanApplicationId = intent.getStringExtra(Constants.LOAN_APPLICATION_ID) + ) + resultIntent.putExtras( + Bundle().apply { + putParcelable( + BankDetailsFragment.PENNY_DROP_BANK_DATA, + pennyDropBankData + ) + } + ) + setResult(Activity.RESULT_OK, resultIntent) + finish() + }, + NEXT_SCREEN_TRANSITION_DELAY ) - resultIntent.putExtras(Bundle().apply { - putParcelable(BankDetailsFragment.PENNY_DROP_BANK_DATA, pennyDropBankData) - }) - setResult(Activity.RESULT_OK, resultIntent) - finish() - }, NEXT_SCREEN_TRANSITION_DELAY) } private fun submitBankDetails() { val loanType = intent.getStringExtra(Constants.LOAN_TYPE) ?: Constants.TYPE_PERSONAL_LOAN - val bankDetail = BankDetail( - beneficiaryName = UserManager.getName(), - accountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), - ifscCode = intent.getStringExtra(Constants.BANK_IFSC), - bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), - type = if (loanType == Constants.TYPE_HOME_LOAN) Constants.ENACH else BankLoanStatusType.DISBURSEMENT - ) - val loanApplicationId = intent.getStringExtra(Constants.PERSONAL_LOAN_APPLICATION_ID) - ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) - loanApplicationId?.let { - viewModel.addBankDetail(bankDetail, it, loanType) - } + val bankDetail = + BankDetail( + beneficiaryName = UserManager.getName(), + accountNumber = intent.getStringExtra(Constants.BANK_ACCOUNT_NUMBER), + ifscCode = intent.getStringExtra(Constants.BANK_IFSC), + bankName = intent.getStringExtra(Constants.BANK_NAME_SELECTED), + type = + if (loanType == Constants.TYPE_HOME_LOAN) Constants.ENACH + else BankLoanStatusType.DISBURSEMENT + ) + val loanApplicationId = + intent.getStringExtra(Constants.PERSONAL_LOAN_APPLICATION_ID) + ?: PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) + loanApplicationId?.let { viewModel.addBankDetail(bankDetail, it, loanType) } } private fun observeBankAccountDetailData() { viewModel.asyncDataResponse.observeNullable(this) { data -> - data?.status?.let { - onGetAddBankResponse(it) - } + data?.status?.let { onGetAddBankResponse(it) } } } @@ -216,7 +227,7 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { apiPollScheduler?.stopApiPoll() data?.let { bankDetail = it.firstOrNull() // considering first item in the bank account list - //TODO; need to handle UI here + // TODO; need to handle UI here } } } @@ -224,9 +235,9 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { private fun getBankAccounts() { if (bankDetail != null) return val loanApplicationId = PreferenceManager.getStringPreference(LOAN_APPLICATION_ID) -// loanApplicationId?.let { -// viewModel.getBankAccounts(it) -// } + // loanApplicationId?.let { + // viewModel.getBankAccounts(it) + // } } private fun initAnimation() { @@ -248,33 +259,30 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { binding.statusDetailsTv.text = getString(R.string.penny_drop) naviAnalyticsEventTracker.onBankVerificationLoaderLands(loanType, journeyType) startCountDownTimer(Constants.ONE_MINUTE_TO_SEC) - } private fun initFirebase(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onGetAddBankResponse(it.status) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { onGetAddBankResponse(it.status) } } } - } firebaseDataHelper?.clear() firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - ADD_BANK_ACCOUNT, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + ADD_BANK_ACCOUNT, + requestId, + notificationPath + ) + } } - private fun onGetAddBankResponse( - status: String? - ) { + private fun onGetAddBankResponse(status: String?) { if (TextUtils.equals(status, FirebaseStatusType.SUCCESS)) { apiPollScheduler?.stopApiPoll() deInitializeAsyncListeners() @@ -284,24 +292,38 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { apiPollScheduler?.stopApiPoll() deInitializeAsyncListeners() cancelTimer() - viewModel.bankDetailAdd.value?.requestId?.let { viewModel.fetchAsyncRequestWithError(it) } + viewModel.bankDetailAdd.value?.requestId?.let { + viewModel.fetchAsyncRequestWithError(it) + } if (intent.getBooleanExtra(GetLoanActivity.IS_FOR_SECOND_LOAN_JOURNEY, false)) { viewModel.fetchRejectionDetails() } else viewModel.checkUiStatus() } } - private fun startAnimationGreenBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.green)) - startAnimationWhiteBackground() - }, Constants.SUCCESS_ANIMATION_WHITE_BG_TIME) + private fun startAnimationGreenBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.green) + ) + startAnimationWhiteBackground() + }, + Constants.SUCCESS_ANIMATION_WHITE_BG_TIME + ) } - private fun startAnimationWhiteBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.white)) - }, Constants.SUCCESS_ANIMATION_GREEN_BG_TIME) + private fun startAnimationWhiteBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.white) + ) + }, + Constants.SUCCESS_ANIMATION_GREEN_BG_TIME + ) } private fun handleLoaderComplete() { @@ -309,18 +331,19 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { binding.successAnimationHolderFl.visibility = View.VISIBLE binding.successAnimation.playAnimation() startAnimationGreenBackground() - binding.successAnimation.addAnimatorListener(object : Animator.AnimatorListener { - override fun onAnimationStart(animation: Animator?) {} + binding.successAnimation.addAnimatorListener( + object : Animator.AnimatorListener { + override fun onAnimationStart(animation: Animator?) {} - override fun onAnimationEnd(animation: Animator?) { - navigateToNextScreen() + override fun onAnimationEnd(animation: Animator?) { + navigateToNextScreen() + } + + override fun onAnimationCancel(animation: Animator?) {} + + override fun onAnimationRepeat(animation: Animator?) {} } - - override fun onAnimationCancel(animation: Animator?) {} - - override fun onAnimationRepeat(animation: Animator?) {} - - }) + ) } private fun handleTimeOutError() { @@ -331,10 +354,10 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { private fun apiPollInit(uploadDataAsyncResponse: UploadDataAsyncResponse) { apiPollScheduler = ApiPollScheduler( - numberOfRetry = uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue( - NUMBER_OF_RETRY - ), - doOnTimeout = { runOnUiThread { handleTimeOutError() } }) { + numberOfRetry = + uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue(NUMBER_OF_RETRY), + doOnTimeout = { runOnUiThread { handleTimeOutError() } } + ) { viewModel.fetchAsyncRequestData(uploadDataAsyncResponse.requestId.orEmpty()) } apiPollScheduler?.scheduleApiPoll() @@ -356,18 +379,15 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { private fun startCountDownTimer(timeInMilliSec: Long) { if (timer == null) { - timer = object : CountDownTimer( - timeInMilliSec, - Constants.MILLISECONDS_PER_SECOND.toLong() - ) { - override fun onTick(millisUntilFinished: Long) { + timer = + object : + CountDownTimer(timeInMilliSec, Constants.MILLISECONDS_PER_SECOND.toLong()) { + override fun onTick(millisUntilFinished: Long) {} + override fun onFinish() { + setUpBankVerificationPendingStatus() + } } - - override fun onFinish() { - setUpBankVerificationPendingStatus() - } - } } timer?.start() } @@ -389,22 +409,18 @@ class BankAccountVerificationLoaderV2Activity : BaseActivity() { override fun onBackPressed() {} - override val screenName: String get() = NaviAnalytics.BANK_ACCOUNT_VERIFICATION_LOADER_V2 override val moduleName: ModuleNameV2 get() = ModuleNameV2.PL - companion object { const val TAG = "BANK_ACCOUNT_VERIFICATION_LOADER" const val PENNY_DROP_FAILURE = "PENNY_DROP_FAILURE" private const val BANK_VERIFICATION_SUCCESS = "BANK_VERIFICATION_SUCCESS" private const val GET_LOAN_VIEW_ANIMATION_DELAY = 1000L - private const val NEXT_SCREEN_TRANSITION_DELAY = - GET_LOAN_VIEW_ANIMATION_DELAY + 100L + private const val NEXT_SCREEN_TRANSITION_DELAY = GET_LOAN_VIEW_ANIMATION_DELAY + 100L private const val NUMBER_OF_RETRY = 24 } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/GetLoanV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/GetLoanV2Activity.kt index 65311764cc..68a6ed5cc5 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/GetLoanV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/GetLoanV2Activity.kt @@ -218,6 +218,9 @@ class GetLoanV2Activity : NaviAnalytics.PL_GETLOAN_PAGE_LANDS_V2 -> { return ChatPLScreens.PL_LOAN_AGREEMENT_SCREEN.name } + NaviAnalytics.DELAYED_DISBURSEMENT_DETAILS_V2_SCREEN -> { + return ChatPLScreens.PL_DELAYED_DISBURSEMENT_SCREEN.name + } else -> return null } } diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/LoanDisbursementLoaderV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/LoanDisbursementLoaderV2Activity.kt index 5374d735f3..a2de834ba5 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/LoanDisbursementLoaderV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/LoanDisbursementLoaderV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.activities import android.animation.Animator @@ -31,7 +38,6 @@ import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.common.navigator.ScreenNavigator import com.naviapp.databinding.ActivityLoanDisbursementLoaderV2Binding import com.naviapp.network.ApiErrorTagType -import com.naviapp.personalloan.getloan.activities.LoanDisbursementLoaderActivity import com.naviapp.personalloan.getloan.viewmodels.LoanDisbursementVM import com.naviapp.personalloanrevamp.getloanRevamp.helper.GetLoanV2ViewHelper import com.naviapp.rewards.ui.RewardDelightActivity @@ -42,9 +48,7 @@ import com.naviapp.utils.orZero class LoanDisbursementLoaderV2Activity : BaseActivity() { private lateinit var binding: ActivityLoanDisbursementLoaderV2Binding - private val viewModel by lazy { - ViewModelProvider(this).get(LoanDisbursementVM::class.java) - } + private val viewModel by lazy { ViewModelProvider(this).get(LoanDisbursementVM::class.java) } private var timer: CountDownTimer? = null private var apiPollScheduler: ApiPollScheduler? = null private var firebaseDataHelper: FirebaseDataHelper? = null @@ -54,7 +58,8 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView(this, R.layout.activity_loan_disbursement_loader_v2) + binding = + DataBindingUtil.setContentView(this, R.layout.activity_loan_disbursement_loader_v2) super.setContentView(binding.root) NaviTrackEvent.sendScreenTransitionEvent(screenName) initError() @@ -76,13 +81,11 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { ) } - private val handleFetchBasicDetailsRetry: View.OnClickListener = View.OnClickListener { _ -> - viewModel.fetchLoanBasicDetails() - } + private val handleFetchBasicDetailsRetry: View.OnClickListener = + View.OnClickListener { _ -> viewModel.fetchLoanBasicDetails() } - private val handleGetDisbursementStatusRetry: View.OnClickListener = View.OnClickListener { _ -> - fetchDisbursementStatus() - } + private val handleGetDisbursementStatusRetry: View.OnClickListener = + View.OnClickListener { _ -> fetchDisbursementStatus() } private fun initObservers() { observeLoanBasicDetails() @@ -117,15 +120,15 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { RewardDelightActivity.AMOUNT, viewModel.dataAsyncResponse.value?.details?.netDisbursalAmount.orZero() ) - navigateNextScreen(screenName = ScreenNavigator.REWARDS_DELIGHT_SCREEN, bundle = bundle) - } ?: kotlin.run { - navigateToNextScreen() + navigateNextScreen( + screenName = ScreenNavigator.REWARDS_DELIGHT_SCREEN, + bundle = bundle + ) } + ?: kotlin.run { navigateToNextScreen() } } - viewModel.rewardsError.observeNonNull(this) { - navigateToNextScreen() - } + viewModel.rewardsError.observeNonNull(this) { navigateToNextScreen() } } private fun observeLoanBasicDetails() { @@ -188,14 +191,16 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { loadTimeEventTracker.onLoadingCompleted(NaviAnalytics.PL_LOAN_DISBURSEMENT_LOAD_TIME) NaviDeepLinkNavigator.navigate( activity = this, - ctaData = CtaData( - url = NaviDeepLinkNavigator.LOAN_APPLICATION_V2.appendStrings( - FORWARD_SLASH.toString(), GetLoanV2ViewHelper.MONEY_DISBURSEMENT_STATUS_V2 - ) - ), - bundle = Bundle().apply { - putString(LOAN_ACCOUNT_NUMBER, viewModel.loanAccountNumber.value) - } + ctaData = + CtaData( + url = + NaviDeepLinkNavigator.LOAN_APPLICATION_V2.appendStrings( + FORWARD_SLASH.toString(), + GetLoanV2ViewHelper.MONEY_DISBURSEMENT_STATUS_V2 + ) + ), + bundle = + Bundle().apply { putString(LOAN_ACCOUNT_NUMBER, viewModel.loanAccountNumber.value) } ) } @@ -215,9 +220,8 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { data.details?.message ?: getString(R.string.sending_amount) initFirebase(it, data.notificationPath.orEmpty()) apiPollInit(it) - } ?: run { - handleTimeOutError() } + ?: run { handleTimeOutError() } } } @@ -247,13 +251,14 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { private fun initFirebase(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onGetDisbursementStatusResponse(it.status, null, null, null, false) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { + onGetDisbursementStatusResponse(it.status, null, null, null, false) + } } } - } firebaseDataHelper = FirebaseDataHelper() firebaseDataHelper?.initFirebaseDataReceiver( lifecycle, @@ -275,19 +280,18 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { private fun startCountDownTimer(timeInMilliSec: Long) { if (timer == null) { - timer = object : CountDownTimer( - timeInMilliSec, - Constants.MILLISECONDS_PER_SECOND.toLong() - ) { - override fun onTick(millisUntilFinished: Long) { - } + timer = + object : + CountDownTimer(timeInMilliSec, Constants.MILLISECONDS_PER_SECOND.toLong()) { + override fun onTick(millisUntilFinished: Long) {} - override fun onFinish() { - setUpLoanDisbursementFailureScreen( - viewModel.loanDisbursementResponse.value?.details?.delayedMessage, null - ) + override fun onFinish() { + setUpLoanDisbursementFailureScreen( + viewModel.loanDisbursementResponse.value?.details?.delayedMessage, + null + ) + } } - } } timer?.start() } @@ -296,7 +300,8 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { apiPollScheduler = ApiPollScheduler( numberOfRetry = NUMBER_OF_RETRY, - doOnTimeout = { runOnUiThread { handleTimeOutError() } }) { + doOnTimeout = { runOnUiThread { handleTimeOutError() } } + ) { viewModel.fetchAsyncRequestData(requestId) } apiPollScheduler?.scheduleApiPoll() @@ -335,24 +340,31 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { ) bundle.putString(MESSAGE_TEXT, binding.statusDetailsTv.text.toString()) NaviDeepLinkNavigator.navigate(activity = this, ctaData = CtaData(url = it)) - } ?: kotlin.run { - viewModel.fetchABExperiment(experimentName = Constants.PL_POST_DISBURSAL_SCREEN_AB_NAME) } + ?: kotlin.run { + viewModel.fetchABExperiment( + experimentName = Constants.PL_POST_DISBURSAL_SCREEN_AB_NAME + ) + } } private fun navigateNextScreen(screenName: String, bundle: Bundle = Bundle()) { - Handler(Looper.getMainLooper()).postDelayed( - { - if (isDead()) return@postDelayed - bundle.putParcelable(Constants.PREVIOUS_SCREEN, PreviousScreenNameRequest(Constants.DISBURSED)) - ScreenNavigator.instance.startActivityWithNoActivityStack( - this, - screenName, - bundle - ) - }, - NEXT_SCREEN_TRANSITION_DELAY - ) + Handler(Looper.getMainLooper()) + .postDelayed( + { + if (isDead()) return@postDelayed + bundle.putParcelable( + Constants.PREVIOUS_SCREEN, + PreviousScreenNameRequest(Constants.DISBURSED) + ) + ScreenNavigator.instance.startActivityWithNoActivityStack( + this, + screenName, + bundle + ) + }, + NEXT_SCREEN_TRANSITION_DELAY + ) } override fun onDestroy() { @@ -362,17 +374,29 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { override fun onBackPressed() {} - private fun startAnimationGreenBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.green)) - startAnimationWhiteBackground() - }, Constants.SUCCESS_ANIMATION_WHITE_BG_TIME) + private fun startAnimationGreenBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.green) + ) + startAnimationWhiteBackground() + }, + Constants.SUCCESS_ANIMATION_WHITE_BG_TIME + ) } - private fun startAnimationWhiteBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.white)) - }, Constants.SUCCESS_ANIMATION_GREEN_BG_TIME) + private fun startAnimationWhiteBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.white) + ) + }, + Constants.SUCCESS_ANIMATION_GREEN_BG_TIME + ) } private fun handleLoaderComplete() { @@ -382,18 +406,21 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { binding.successAnimationHolderFl.visibility = View.VISIBLE binding.successAnimation.playAnimation() startAnimationGreenBackground() - binding.successAnimation.addAnimatorListener(object : Animator.AnimatorListener { - override fun onAnimationStart(animation: Animator?) {} - override fun onAnimationEnd(animation: Animator?) { - viewModel.fetchRewardsDetails( - type = ModuleNameV2.PL.name, - typeId = PreferenceManager.getStringPreference(LOAN_APPLICATION_ID).orEmpty() - ) - } + binding.successAnimation.addAnimatorListener( + object : Animator.AnimatorListener { + override fun onAnimationStart(animation: Animator?) {} + override fun onAnimationEnd(animation: Animator?) { + viewModel.fetchRewardsDetails( + type = ModuleNameV2.PL.name, + typeId = + PreferenceManager.getStringPreference(LOAN_APPLICATION_ID).orEmpty() + ) + } - override fun onAnimationCancel(animation: Animator?) {} - override fun onAnimationRepeat(animation: Animator?) {} - }) + override fun onAnimationCancel(animation: Animator?) {} + override fun onAnimationRepeat(animation: Animator?) {} + } + ) } companion object { @@ -402,4 +429,4 @@ class LoanDisbursementLoaderV2Activity : BaseActivity() { private const val NEXT_SCREEN_TRANSITION_DELAY = 1000L private const val NUMBER_OF_RETRY = 12 } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/SkipMandateV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/SkipMandateV2Activity.kt index d8c49c66c0..999a251747 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/SkipMandateV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/activities/SkipMandateV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.activities import android.os.Bundle @@ -28,8 +35,8 @@ import com.naviapp.utils.setMargin import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class SkipMandateV2Activity : BaseActivity(), FooterViewV2.FooterInteractionListener, - NaviHeaderView.InteractionListener { +class SkipMandateV2Activity : + BaseActivity(), FooterViewV2.FooterInteractionListener, NaviHeaderView.InteractionListener { private lateinit var binding: ActivitySkipMandateV2Binding private val skipMandateVM by lazy { ViewModelProvider(this).get(SkipMandateV2VM::class.java) } @@ -50,13 +57,9 @@ class SkipMandateV2Activity : BaseActivity(), FooterViewV2.FooterInteractionList binding.footerView.binding.knowMoreTv.setOnClickListener { skipMandateVM.skipMandateResponse.value?.content?.dataSecurity?.let { val infoBottomSheet = InformationBottomSheet.getInstance(it) - safelyShowBottomSheet( - infoBottomSheet, - InformationBottomSheet.TAG - ) + safelyShowBottomSheet(infoBottomSheet, InformationBottomSheet.TAG) } } - } private fun initUI() { @@ -115,9 +118,7 @@ class SkipMandateV2Activity : BaseActivity(), FooterViewV2.FooterInteractionList } binding.skipMandateBinder = skipMandateResponse - binding.itemsMargin = Margin( - topDp = 12.0f - ) + binding.itemsMargin = Margin(topDp = 12.0f) binding.itemTitleStyle = R.style.NaviSansSemiBoldExtraSmallDescColorOne binding.footerListener = this binding.footerView.showDataSafetyHeader() @@ -141,19 +142,14 @@ class SkipMandateV2Activity : BaseActivity(), FooterViewV2.FooterInteractionList override fun onFooterNextPressed(nextCta: CtaData?) { nextCta?.let { - NaviDeepLinkNavigator.navigate( - activity = this, - ctaData = it, - finish = true - ) + NaviDeepLinkNavigator.navigate(activity = this, ctaData = it, finish = true) finishAffinity() } - if(nextCta?.title?.orEmpty() == "Setup auto-pay"){ + if (nextCta?.title?.orEmpty() == "Setup auto-pay") { analyticsEventTracker.onSetUpAutoPayClicked(loanApplicationId) - }else{ + } else { analyticsEventTracker.onContinueClicked(loanApplicationId) } - } override fun setProperties( @@ -191,7 +187,11 @@ class SkipMandateV2Activity : BaseActivity(), FooterViewV2.FooterInteractionList ) } + override fun onBackPressed() { + launchHome() + } + companion object { const val TAG = "SKIP_MANDATE_V2" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/LoanDetailsV2WidgetAdapter.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/LoanDetailsV2WidgetAdapter.kt index bac996f383..17f5b2d451 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/LoanDetailsV2WidgetAdapter.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/LoanDetailsV2WidgetAdapter.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.adapters /* * diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SearchPopularBankAdapter.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SearchPopularBankAdapter.kt index 48108c523a..4f4b81840c 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SearchPopularBankAdapter.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SearchPopularBankAdapter.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.adapters import android.content.Context @@ -69,5 +76,4 @@ class SearchPopularBankAdapter(private val context: Context) : BaseAdapter() { var itemIv = binding.itemIv } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SelectBankAdapter.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SelectBankAdapter.kt index 01d8686c46..534b07375f 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SelectBankAdapter.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/adapters/SelectBankAdapter.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.adapters import android.annotation.SuppressLint @@ -7,7 +14,6 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import com.bumptech.glide.Glide import com.navi.common.utils.orZero import com.naviapp.R import com.naviapp.databinding.BankSearchSuggestedResultViewBinding @@ -31,10 +37,11 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : return when (viewType) { VIEW_TYPE_POPULAR_BANK -> { val binding = SearchPopularBankRowItemBinding.inflate(inflater, parent, false) - binding.popularBankView.layoutParams = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT - ) + binding.popularBankView.layoutParams = + FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) PopularBankVH(binding) } VIEW_TYPE_ALL_SUGGESTED_BANK_HEADING -> { @@ -58,7 +65,6 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : val binding = holder.binding binding.popularBankView.setListener(listener) binding.popularBankView.setData(popularBanks) - } is HeadingVH -> { val binding = holder.binding @@ -71,8 +77,8 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : binding.descriptionTv.text = bank.message binding.bankImageIv.setImageResource(R.drawable.ic_rounded_bank_black_and_white) binding.divider.isVisible = false -// bank.iconUrl?.let { Glide.with(binding.root).load(it).circleCrop() -// .into(binding.bankImageIv) } + // bank.iconUrl?.let { Glide.with(binding.root).load(it).circleCrop() + // .into(binding.bankImageIv) } binding.descriptionTv.visibility = if (bank.serviceable) View.GONE else View.VISIBLE @@ -94,11 +100,9 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : isLabelForAllSupportedBanksNeeded -> VIEW_TYPE_ALL_SUGGESTED_BANK_HEADING else -> VIEW_TYPE_ALL_SUGGESTED_BANK } - } else if (position == 1 && isLabelForAllSupportedBanksNeeded) { VIEW_TYPE_ALL_SUGGESTED_BANK_HEADING - } else - VIEW_TYPE_ALL_SUGGESTED_BANK + } else VIEW_TYPE_ALL_SUGGESTED_BANK } class PopularBankVH(val binding: SearchPopularBankRowItemBinding) : @@ -120,7 +124,7 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : this.banks.add(Bank()) // added empty item for Popular banks view } if (data.allSupportedBanks?.size.orZero() > 0) { - if (isLabelForAllSupportedBanksNeeded){ + if (isLabelForAllSupportedBanksNeeded) { this.banks.add(Bank()) // for Header } this.banks.addAll(data.allSupportedBanks.orEmpty()) @@ -133,4 +137,4 @@ class SelectBankAdapter(private val listener: OnSelectBankListener?) : private const val VIEW_TYPE_ALL_SUGGESTED_BANK_HEADING = 1 private const val VIEW_TYPE_ALL_SUGGESTED_BANK = 2 } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/AutoDebitCardDetailView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/AutoDebitCardDetailView.kt index dba8129b8b..9faa2bd4e4 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/AutoDebitCardDetailView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/AutoDebitCardDetailView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.customview import android.content.Context @@ -11,7 +18,6 @@ import com.naviapp.databinding.AutoDebitCardDetailBinding import com.naviapp.databinding.ViewTextSymbolItemV2Binding import com.naviapp.models.response.GenericWidgetBody - class AutoDebitCardDetailView(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) { @@ -20,10 +26,11 @@ class AutoDebitCardDetailView(context: Context?, attrs: AttributeSet?) : init { val inflater = LayoutInflater.from(context) binding = DataBindingUtil.inflate(inflater, R.layout.auto_debit_card_detail, this, true) - layoutParams = ConstraintLayout.LayoutParams( - ConstraintLayout.LayoutParams.MATCH_PARENT, - ConstraintLayout.LayoutParams.WRAP_CONTENT - ) + layoutParams = + ConstraintLayout.LayoutParams( + ConstraintLayout.LayoutParams.MATCH_PARENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ) } fun setProperties(autoDebitSteps: GenericWidgetBody) { @@ -36,4 +43,4 @@ class AutoDebitCardDetailView(context: Context?, attrs: AttributeSet?) : binding.autoDebitStepsRv.addView(childBinding.root, binding.autoDebitStepsRv.childCount) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/EnachTutorialStepsView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/EnachTutorialStepsView.kt index 4688c3f164..4833484758 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/EnachTutorialStepsView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/EnachTutorialStepsView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.customview import android.content.Context @@ -6,11 +13,11 @@ import android.view.LayoutInflater import androidx.constraintlayout.widget.ConstraintLayout import androidx.databinding.DataBindingUtil import com.navi.common.utils.orElse +import com.navi.common.utils.setCornerRadius import com.naviapp.R import com.naviapp.databinding.EnachTutorialStepsBinding import com.naviapp.models.response.GenericWidgetBody import com.naviapp.utils.IconUtils -import com.naviapp.utils.setCornerRadius class EnachTutorialStepsView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) { @@ -19,8 +26,7 @@ class EnachTutorialStepsView(context: Context, attrs: AttributeSet?) : init { val inflater = LayoutInflater.from(context) - binding = - DataBindingUtil.inflate(inflater, R.layout.enach_tutorial_steps, this, true) + binding = DataBindingUtil.inflate(inflater, R.layout.enach_tutorial_steps, this, true) layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) binding.enachStepsCl.setCornerRadius(8F) } @@ -47,6 +53,5 @@ class EnachTutorialStepsView(context: Context, attrs: AttributeSet?) : binding.thirdView.iconIv ) binding.thirdView.textTv.text = "3" - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/GstRadioListView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/GstRadioListView.kt index a4688e438d..ae7297111a 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/GstRadioListView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/GstRadioListView.kt @@ -18,8 +18,8 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible -import com.navi.common.utils.setShakeAnimation import com.navi.design.utils.getNaviDrawable +import com.navi.insurance.util.setShakeAnimation import com.naviapp.R import com.naviapp.databinding.GstRadioButtonLayoutBinding import com.naviapp.models.response.GSTDetail diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/LoanSummaryCardView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/LoanSummaryCardView.kt index 67601ea8d6..853c3fbe35 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/LoanSummaryCardView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/LoanSummaryCardView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.customview import android.content.Context @@ -9,24 +16,20 @@ import com.naviapp.R import com.naviapp.databinding.StyledKeyValueV2CardBinding import com.naviapp.personalloanrevamp.models.response.DetailCard - class LoanSummaryCardView(context: Context, attrs: AttributeSet? = null) : CardView(context, attrs) { - private var binding = StyledKeyValueV2CardBinding.inflate( - LayoutInflater.from(context), this, true - ) + private var binding = + StyledKeyValueV2CardBinding.inflate(LayoutInflater.from(context), this, true) init { - radius = resources.getDimension(R.dimen.layout_dp_8) - elevation = resources.getDimension(R.dimen.layout_dp_0) + radius = resources.getDimension(R.dimen.layout_dp_8) + elevation = resources.getDimension(R.dimen.layout_dp_0) } - fun setProperties( - details : DetailCard - ) { + fun setProperties(details: DetailCard) { binding.styledCardBinder = details binding.keyValueStyle = R.style.NaviSansSemiBold binding.detailsMargin = Margin(topDp = 20.0f) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferImprovementCardViewV2.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferImprovementCardViewV2.kt index 01fe2e92c9..8295f0f196 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferImprovementCardViewV2.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferImprovementCardViewV2.kt @@ -8,7 +8,6 @@ package com.naviapp.personalloanrevamp.getloanRevamp.customview import android.content.Context -import android.graphics.Color import android.util.AttributeSet import android.view.LayoutInflater import android.view.View @@ -24,32 +23,33 @@ import com.naviapp.databinding.OfferImprovementCardViewLayoutV2Binding import com.naviapp.models.response.OfferImprovementDocumentsCardData import com.naviapp.utils.IconUtils import com.naviapp.utils.setTextColorFromString -import com.naviapp.utils.setTextDrawableColor class OfferImprovementCardViewV2(context: Context, attrs: AttributeSet?) : CardView(context, attrs) { - private val binding = OfferImprovementCardViewLayoutV2Binding.inflate( - LayoutInflater.from(context), this, true - ) + private val binding = + OfferImprovementCardViewLayoutV2Binding.inflate(LayoutInflater.from(context), this, true) init { val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) layoutParams.topMargin = resources.getDimension(R.dimen.layout_dp_16).toInt() this.layoutParams = layoutParams elevation = resources.getDimension(R.dimen.layout_dp_0) - binding.benefitTvBackground.background = getNaviDrawable( - radii = CornerRadius( - leftBottom = resources.getDimension(R.dimen.layout_dp_8), - rightBottom = resources.getDimension(R.dimen.layout_dp_8) - ), - backgroundColor = ResourcesCompat.getColor(resources, R.color.green_one, null) - ) - binding.rootItem.background = getNaviDrawable( - strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), - strokeColor = ResourcesCompat.getColor(resources, R.color.container_bg_color, null), - cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt() - ) + binding.benefitTvBackground.background = + getNaviDrawable( + radii = + CornerRadius( + leftBottom = resources.getDimension(R.dimen.layout_dp_8), + rightBottom = resources.getDimension(R.dimen.layout_dp_8) + ), + backgroundColor = ResourcesCompat.getColor(resources, R.color.green_one, null) + ) + binding.rootItem.background = + getNaviDrawable( + strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), + strokeColor = ResourcesCompat.getColor(resources, R.color.container_bg_color, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt() + ) } fun setProperties(offerImprovementData: OfferImprovementDocumentsCardData) { @@ -66,20 +66,19 @@ class OfferImprovementCardViewV2(context: Context, attrs: AttributeSet?) : offerImprovementData.verificationStatus?.let { it.iconCode?.let { iconCode -> binding.subtitleTv.setCompoundDrawablesWithIntrinsicBounds( - IconUtils.getIconResourceId(iconCode), 0, 0, 0 + IconUtils.getIconResourceId(iconCode), + 0, + 0, + 0 ) } binding.subtitleTv.visibility = View.VISIBLE binding.subtitleTv.text = it.title if (isValidHexColor(it.titleColor)) { - binding.subtitleTv.apply { - setTextColorFromString(it.titleColor) - } + binding.subtitleTv.apply { setTextColorFromString(it.titleColor) } } } - offerImprovementData.cta?.let { - binding.arrowIv.visibility = View.VISIBLE - } + offerImprovementData.cta?.let { binding.arrowIv.visibility = View.VISIBLE } if (offerImprovementData.verified.orFalse()) binding.arrowIv.setImageResource(R.drawable.ic_rounded_green_tick) @@ -88,6 +87,5 @@ class OfferImprovementCardViewV2(context: Context, attrs: AttributeSet?) : binding.benefitTv.isVisible = true binding.benefitTv.text = it } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeBenefitsV2CardView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeBenefitsV2CardView.kt index a6af960610..9031e4fa14 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeBenefitsV2CardView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeBenefitsV2CardView.kt @@ -4,6 +4,7 @@ * * All rights reserved. Strictly confidential * */ + package com.naviapp.personalloanrevamp.getloanRevamp.customview import android.content.Context @@ -21,9 +22,8 @@ class OfferUpgradeBenefitsV2CardView(context: Context, attrs: AttributeSet?) : private val analyticsEventTracker = NaviAnalytics.naviAnalytics.LoanOfferUpgrade() - private val binding = OfferUpgradeBenefitCardV2ViewBinding.inflate( - LayoutInflater.from(context), this, true - ) + private val binding = + OfferUpgradeBenefitCardV2ViewBinding.inflate(LayoutInflater.from(context), this, true) fun setProperties( loanOfferUpgradedItemTitle: LoanOfferUpgradedItemsTitle? = null, @@ -31,9 +31,7 @@ class OfferUpgradeBenefitsV2CardView(context: Context, attrs: AttributeSet?) : ) { binding.loanTitleTv.text = loanOfferUpgradedItemTitle?.loanAmountTitle binding.loanAmountTv.text = loanOfferUpgradedItemTitle?.loanAmount - loanOfferUpgradedItemTitle?.iconCode?.let { - IconUtils.updateIcon(it, binding.iconImv) - } + loanOfferUpgradedItemTitle?.iconCode?.let { IconUtils.updateIcon(it, binding.iconImv) } loanOfferUpgradedItems?.getOrNull(0)?.let { binding.increasedAmountTv.text = it.value @@ -46,10 +44,8 @@ class OfferUpgradeBenefitsV2CardView(context: Context, attrs: AttributeSet?) : } if (loanOfferUpgradedItems.isNullOrEmpty().not()) { val valueList = mutableListOf() - loanOfferUpgradedItems?.forEach { element -> - valueList.add(element.value.orEmpty()) - } + loanOfferUpgradedItems?.forEach { element -> valueList.add(element.value.orEmpty()) } analyticsEventTracker.onOfferUpgraded(valueList) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeCardView.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeCardView.kt index 1cfa1d742c..9e6ee9c6f1 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeCardView.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/customview/OfferUpgradeCardView.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.customview /* @@ -24,10 +31,8 @@ import com.naviapp.utils.setMargin class OfferUpgradeCardView(context: Context, attrs: AttributeSet? = null) : CardView(context, attrs) { - private val binding = OfferUpgradeCardViewBinding.inflate( - LayoutInflater.from(context), - this, true - ) + private val binding = + OfferUpgradeCardViewBinding.inflate(LayoutInflater.from(context), this, true) init { layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) @@ -43,17 +48,11 @@ class OfferUpgradeCardView(context: Context, attrs: AttributeSet? = null) : listener: LoanDetailsV2WidgetAdapterListener? ) { offerUpgradeCardWidgetConfig?.let { widgetConfig -> - widgetConfig.widgetLayoutParams?.margin?.let { margin -> - this.setMargin(margin) - } - widgetConfig.widgetBody?.let { widgetBody -> - binding.offerBinder = widgetBody - } + widgetConfig.widgetLayoutParams?.margin?.let { margin -> this.setMargin(margin) } + widgetConfig.widgetBody?.let { widgetBody -> binding.offerBinder = widgetBody } if (widgetConfig.widgetBody?.description != null) { binding.iconIv.isVisible = true - widgetConfig.widgetBody.iconCode?.let { - IconUtils.updateIcon(it, binding.iconIv) - } + widgetConfig.widgetBody.iconCode?.let { IconUtils.updateIcon(it, binding.iconIv) } } else { binding.iconIv.isVisible = false } @@ -67,5 +66,4 @@ class OfferUpgradeCardView(context: Context, attrs: AttributeSet? = null) : super.onDetachedFromWindow() binding.unbind() } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/BankDetailsV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/BankDetailsV2Fragment.kt index 7e4726c4f9..988ca73d4d 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/BankDetailsV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/BankDetailsV2Fragment.kt @@ -19,12 +19,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import android.widget.Toast +import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat +import androidx.core.view.updateLayoutParams import androidx.core.widget.TextViewCompat import androidx.core.widget.addTextChangedListener import androidx.lifecycle.ViewModelProvider +import com.navi.amc.common.view.InformationView import com.navi.analytics.utils.NaviTrackEvent import com.navi.analytics.uxcam.UxcamUtil import com.navi.base.model.CtaData @@ -36,6 +38,7 @@ import com.navi.common.utils.toggleViewDisability import com.navi.design.font.FontWeightEnum import com.navi.design.utils.getFontStyle import com.navi.naviwidgets.base.BaseInputWidget +import com.navi.naviwidgets.widgets.textdisplay.Margin import com.navi.naviwidgets.widgets.textdisplay.Padding import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics @@ -52,7 +55,7 @@ import com.naviapp.network.ApiErrorTagType.FETCH_LOAN_BASIC_DETAILS_ERROR import com.naviapp.personalloan.getloan.activities.BankAccountVerificationLoaderActivity import com.naviapp.personalloan.getloan.activities.GetLoanActivity import com.naviapp.personalloan.getloan.activities.GetLoanActivity.Companion.IS_FOR_SECOND_LOAN_JOURNEY -import com.naviapp.personalloan.getloan.bankdetails.fragments.* +import com.naviapp.personalloan.getloan.bankdetails.fragments.BankDetailsFragment import com.naviapp.personalloan.getloan.bankdetails.listeners.FindIfscListener import com.naviapp.personalloan.getloan.bankdetails.listeners.OnSelectBankListener import com.naviapp.personalloan.getloan.bankdetails.viewmodels.BankDetailsVM @@ -673,7 +676,30 @@ class BankDetailsV2Fragment : } ?: run { binding.bankNameSearch.setError(getString(R.string.bank_name_error_header)) - context?.toast(R.string.select_valid_bank) + viewModel.toastId.value?.let { + binding.root.findViewById(it).visibility = View.VISIBLE + } ?: run { + val view = context?.let { InformationView(it) } + view?.id = View.generateViewId() + view?.setProperties( + BankDetailsV2Helper.getCustomToastProperties( + getString(R.string.select_valid_bank), + null + ), + ) + view?.setMargin( + Margin( + startDp = 16.0f, + endDp = 16.0f, + bottomDp = 144.0f + ) + ) + view?.updateLayoutParams { + this.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID + } + binding.container.addView(view) + viewModel.toastId.value = view?.id + } } } @@ -768,6 +794,9 @@ class BankDetailsV2Fragment : bank.name?.let { binding.bankNameSearch.setText(it, false, false) binding.bankNameSearch.setError(null) + viewModel.toastId.value?.let { toastIdValue -> + binding.root.findViewById(toastIdValue).visibility = View.GONE + } } binding.bankAccountNumberLt.updateTextInputData("") binding.ifscLt.widgetBinding.plainTextInput.requestFocus() @@ -781,11 +810,7 @@ class BankDetailsV2Fragment : } override fun onClickUnserviceableBank() { - context?.toast( - getString(R.string.this_bank_is_not_supported), - offsetY = 200, - length = Toast.LENGTH_SHORT - ) + } override fun onFooterBackPressed(backCta: CtaData?) { diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/DelayedDisbursementV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/DelayedDisbursementV2Fragment.kt index b3ec47601e..9d0e641d12 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/DelayedDisbursementV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/DelayedDisbursementV2Fragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -25,7 +25,9 @@ import com.naviapp.utils.IconUtils class DelayedDisbursementV2Fragment : BaseFragment() { private lateinit var binding: DelayedDisbursementV2LayoutBinding - private val viewModel by lazy { ViewModelProvider(this).get(DelayedDisbursementViewModel::class.java) } + private val viewModel by lazy { + ViewModelProvider(this).get(DelayedDisbursementViewModel::class.java) + } private val analyticsEventTracker = NaviAnalytics.naviAnalytics.FullPageProcessingDetail() override fun onCreateView( @@ -53,20 +55,16 @@ class DelayedDisbursementV2Fragment : BaseFragment() { binding.actionBtn.setOnClickListener { viewModel.delayedDisbursementDetails.value?.content?.let { it.firstOrNull()?.ctaData?.let { - NaviDeepLinkNavigator.navigate( - activity = activity, - ctaData = it, - finish = true - ) + NaviDeepLinkNavigator.navigate(activity = activity, ctaData = it, finish = true) activity?.finishAffinity() } - } ?: kotlin.run { - ScreenNavigator.instance.startActivityWithNoActivityStack( - activity = activity, - screenName = ScreenNavigator.HOME - ) } - + ?: kotlin.run { + ScreenNavigator.instance.startActivityWithNoActivityStack( + activity = activity, + screenName = ScreenNavigator.HOME + ) + } } } @@ -81,10 +79,7 @@ class DelayedDisbursementV2Fragment : BaseFragment() { binding.actionBtn.setProperties( title = data?.ctaData?.title ?: resources.getString(R.string.go_home) ) - data?.iconCode?.let { - IconUtils.updateIcon(it, binding.ivPending) - } - + data?.iconCode?.let { IconUtils.updateIcon(it, binding.ivPending) } } } } @@ -97,9 +92,7 @@ class DelayedDisbursementV2Fragment : BaseFragment() { const val TAG = "DelayedDisbursementV2Fragment" fun getInstance(bundle: Bundle?): DelayedDisbursementV2Fragment { - return DelayedDisbursementV2Fragment().apply { - arguments = bundle - } + return DelayedDisbursementV2Fragment().apply { arguments = bundle } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/EmiSelectorV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/EmiSelectorV2Fragment.kt index e9c59d34a7..9bc7c21ea7 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/EmiSelectorV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/EmiSelectorV2Fragment.kt @@ -21,6 +21,7 @@ import com.navi.base.sharedpref.PreferenceManager import com.navi.common.model.Money import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.* +import com.navi.common.utils.setCornerRadius import com.navi.design.calendar.adapter.NaviCalendarViewAdapter import com.navi.design.calendar.model.DateStyleModel import com.navi.design.calendar.model.WeekDayData diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/FreshLoanDetailsV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/FreshLoanDetailsV2Fragment.kt index d3a40ca0f4..961f43aa75 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/FreshLoanDetailsV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/FreshLoanDetailsV2Fragment.kt @@ -10,7 +10,6 @@ package com.naviapp.personalloanrevamp.getloanRevamp.fragments import android.content.Context import android.os.Bundle import android.text.TextUtils -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -646,8 +645,12 @@ class FreshLoanDetailsV2Fragment : } } } - if(isCustomizeTenureSelected.orFalse().not()){ - reloadPage(viewModel.selectedLoanAmount.value, viewModel.selectedFirstEmiDate.value, viewModel.selectedTenure.value) + if (isCustomizeTenureSelected.orFalse().not()) { + reloadPage( + viewModel.selectedLoanAmount.value, + viewModel.selectedFirstEmiDate.value, + viewModel.selectedTenure.value + ) } } @@ -684,7 +687,11 @@ class FreshLoanDetailsV2Fragment : } } } - reloadPage(viewModel.selectedLoanAmount.value, viewModel.selectedFirstEmiDate.value, viewModel.selectedTenure.value) + reloadPage( + viewModel.selectedLoanAmount.value, + viewModel.selectedFirstEmiDate.value, + viewModel.selectedTenure.value + ) } private fun openEmiCalendar() { @@ -787,14 +794,14 @@ class FreshLoanDetailsV2Fragment : } } - private fun reloadPage(loanAmount: Double?, firstEmiDueDate: String?, tenureInMonths: Int? = null) { + private fun reloadPage( + loanAmount: Double?, + firstEmiDueDate: String?, + tenureInMonths: Int? = null + ) { viewModel.offer.value?.let { - val loanFeeDetailsRequest = constructLoanRequestForFeeDetails( - it, - loanAmount, - firstEmiDueDate, - tenureInMonths - ) + val loanFeeDetailsRequest = + constructLoanRequestForFeeDetails(it, loanAmount, firstEmiDueDate, tenureInMonths) showLoader() viewModel.fetchFeeDetails(loanFeeDetailsRequest) } diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/InReviewV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/InReviewV2Fragment.kt index cd0f524bc9..fc87c0043f 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/InReviewV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/InReviewV2Fragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,9 +13,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider +import com.navi.common.ui.fragment.BaseFragment import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics -import com.navi.common.ui.fragment.BaseFragment import com.naviapp.common.customview.NaviHeaderView import com.naviapp.common.navigator.ScreenNavigator import com.naviapp.dashboard.listeners.FragmentInteractionListener @@ -57,12 +57,8 @@ class InReviewV2Fragment : BaseFragment() { private fun initUi() { eventTracker.onKycAddressBlockerPageLands() - arguments?.getString(TITLE)?.let { - binding.tvPending.text = it - } - arguments?.getString(DESCRIPTION)?.let { - binding.tvDescription.text = it - } + arguments?.getString(TITLE)?.let { binding.tvPending.text = it } + arguments?.getString(DESCRIPTION)?.let { binding.tvDescription.text = it } } private fun initListeners() { @@ -85,11 +81,12 @@ class InReviewV2Fragment : BaseFragment() { fun getInstance(bundle: Bundle?): InReviewV2Fragment { return InReviewV2Fragment().apply { - arguments = Bundle().apply { - putString(TITLE, bundle?.getString(TITLE)) - putString(DESCRIPTION, bundle?.getString(DESCRIPTION)) - } + arguments = + Bundle().apply { + putString(TITLE, bundle?.getString(TITLE)) + putString(DESCRIPTION, bundle?.getString(DESCRIPTION)) + } } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/SelectBankV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/SelectBankV2Fragment.kt index ff85d4e0a3..94853bb3a0 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/SelectBankV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/SelectBankV2Fragment.kt @@ -18,17 +18,19 @@ import com.navi.common.utils.observeNonNull import com.naviapp.R import com.naviapp.common.viewmodel.ActiveLoanDetailsVM import com.naviapp.databinding.SelectBankV2LayoutBinding +import com.naviapp.models.response.Bank import com.naviapp.models.response.BankDetailsHeaderData import com.naviapp.personalloan.getloan.bankdetails.listeners.OnSelectBankListener import com.naviapp.personalloan.getloan.bankdetails.viewmodels.BankDetailsVM import com.naviapp.personalloanrevamp.getloanRevamp.adapters.SelectBankAdapter import com.naviapp.personalloanrevamp.getloanRevamp.customview.SearchV2Field +import com.naviapp.personalloanrevamp.getloanRevamp.helper.BankDetailsV2Helper import com.naviapp.utils.IconUtils import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class SelectBankV2Fragment : - BaseBottomSheet(), SearchV2Field.SearchFieldListener { + BaseBottomSheet(), SearchV2Field.SearchFieldListener, OnSelectBankListener { private lateinit var binding: SelectBankV2LayoutBinding private var adapter: SelectBankAdapter? = null private val viewModel by lazy { ViewModelProvider(this).get(BankDetailsVM::class.java) } @@ -52,7 +54,7 @@ class SelectBankV2Fragment : } private fun initUI() { - adapter = SelectBankAdapter(bankSelectListener) + adapter = SelectBankAdapter(this) binding.bankNameSf.setOnSearchListener(this) binding.bankNameSf.setHint(R.string.search) arguments?.getString(SELECTED_BANK)?.let { binding.bankNameSf.setText(it) } @@ -142,4 +144,19 @@ class SelectBankV2Fragment : HOME_LOAN, ACCOUNT_AGGREGATOR } + + override fun onSelectBank(bank: Bank) { + binding.toast.visibility = View.GONE + bankSelectListener?.onSelectBank(bank) + } + + override fun onClickUnserviceableBank() { + binding.toast.setProperties( + BankDetailsV2Helper.getCustomToastProperties( + getString(R.string.this_bank_is_not_supported_title), + getString(R.string.kindly_select_some_other_bank_subtitle) + ) + ) + bankSelectListener?.onClickUnserviceableBank() + } } diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/UpcomingEmiDetailsV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/UpcomingEmiDetailsV2Fragment.kt index 772e38b0ac..4e7bf8336e 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/UpcomingEmiDetailsV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/fragments/UpcomingEmiDetailsV2Fragment.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.fragments import android.app.Activity @@ -11,6 +18,7 @@ import androidx.lifecycle.ViewModelProvider import com.navi.common.model.Money import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.orZero +import com.navi.common.utils.setCornerRadius import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.customview.NaviHeaderView @@ -25,7 +33,6 @@ import com.naviapp.personalloan.getloan.loandetails.fragments.EmiSelectorFragmen import com.naviapp.personalloan.getloan.loandetails.viewmodels.EmiSelectorVM import com.naviapp.personalloanrevamp.getloanRevamp.helper.GetLoanV2ViewHelper import com.naviapp.utils.orZero -import com.naviapp.utils.setCornerRadius import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -57,12 +64,12 @@ class UpcomingEmiDetailsV2Fragment : BaseFragment(), BackListener { } private fun initUI() { - arguments?.getParcelable(EmiSelectorFragment.LOAN_FEE_DETAILS_REQUEST) + arguments + ?.getParcelable(EmiSelectorFragment.LOAN_FEE_DETAILS_REQUEST) ?.let { showLoader() viewModel.fetchUpcomingEmiDates(it) } - } private fun initObserver() { @@ -74,7 +81,6 @@ class UpcomingEmiDetailsV2Fragment : BaseFragment(), BackListener { } } - private fun processHeader(header: Header?) { header?.let { headerListener?.setProperties( @@ -100,27 +106,25 @@ class UpcomingEmiDetailsV2Fragment : BaseFragment(), BackListener { } private fun getFormattedBundle(): Bundle { - val bundle = Bundle().apply { - putParcelable( - EmiSelectorV2Fragment.LOAN_AMOUNT, arguments?.getParcelable( - EmiSelectorV2Fragment.LOAN_AMOUNT + val bundle = + Bundle().apply { + putParcelable( + EmiSelectorV2Fragment.LOAN_AMOUNT, + arguments?.getParcelable(EmiSelectorV2Fragment.LOAN_AMOUNT) ) - ) - putDouble( - EmiSelectorV2Fragment.RATE_OF_INTEREST, arguments?.getDouble( - EmiSelectorV2Fragment.RATE_OF_INTEREST - ).orZero() - ) - putInt( - EmiSelectorV2Fragment.TENURE, - arguments?.getInt(EmiSelectorV2Fragment.TENURE).orZero() - ) - putString( - EmiSelectorV2Fragment.SELECTED_EMI_DATE, arguments?.getString( - EmiSelectorV2Fragment.SELECTED_EMI_DATE + putDouble( + EmiSelectorV2Fragment.RATE_OF_INTEREST, + arguments?.getDouble(EmiSelectorV2Fragment.RATE_OF_INTEREST).orZero() ) - ) - } + putInt( + EmiSelectorV2Fragment.TENURE, + arguments?.getInt(EmiSelectorV2Fragment.TENURE).orZero() + ) + putString( + EmiSelectorV2Fragment.SELECTED_EMI_DATE, + arguments?.getString(EmiSelectorV2Fragment.SELECTED_EMI_DATE) + ) + } return bundle } @@ -162,13 +166,11 @@ class UpcomingEmiDetailsV2Fragment : BaseFragment(), BackListener { override val screenName: String get() = NaviAnalytics.UPCOMING_EMI_DETAILS_SCREEN_V2 - companion object { const val TAG = "UPCOMING_EMI_DETAIL_V2" @JvmStatic - fun newInstance(bundle: Bundle?) = UpcomingEmiDetailsV2Fragment().apply { - arguments = bundle - } + fun newInstance(bundle: Bundle?) = + UpcomingEmiDetailsV2Fragment().apply { arguments = bundle } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/BankDetailsV2Helper.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/BankDetailsV2Helper.kt index 0c6ca1f7f8..0f0f28ab49 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/BankDetailsV2Helper.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/BankDetailsV2Helper.kt @@ -1,6 +1,11 @@ package com.naviapp.personalloanrevamp.getloanRevamp.helper import android.content.Context +import com.navi.amc.common.model.InformationCardData +import com.navi.design.font.FontWeightEnum +import com.navi.design.textview.model.NaviSpan +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.utils.NaviWidgetIconUtils import com.navi.naviwidgets.widgets.TextInputUtil import com.navi.naviwidgets.widgets.labledtextinput.InputTextWidgetMeta import com.navi.naviwidgets.widgets.labledtextinput.LabeledTextInputWidgetModelV2 @@ -38,4 +43,44 @@ object BankDetailsV2Helper { } ) } + + fun getCustomToastProperties(title: String?, subtitle: String?): InformationCardData { + return InformationCardData( + leftIcon = NaviWidgetIconUtils.ICON_ERROR_OUTLINED_ROUND_EXCLAMATION, + rightIcon = NaviWidgetIconUtils.CROSS, + bgColor = "#FFFFEAEA", + title = getTitleTextProperties(title), + subtitle = getSubtitleTextProperties(subtitle) + ) + } + + private fun getTitleTextProperties(title: String?): TextWithStyle? { + return title?.let { + TextWithStyle( + text = title, + style = listOf( + NaviSpan( + fontSize = 14.0, + spanColor = "#EF0000", + fontName = FontWeightEnum.BOLD.name + ) + ) + ) + } + } + + private fun getSubtitleTextProperties(subtitle: String?): TextWithStyle? { + return subtitle?.let { + TextWithStyle( + text = subtitle, + style = listOf( + NaviSpan( + fontSize = 12.0, + spanColor = "#4D4D4D", + fontName = FontWeightEnum.SEMI_BOLD.name + ) + ) + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/FreshLoanDetailsV2Helper.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/FreshLoanDetailsV2Helper.kt index d54f610383..3314d0e1aa 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/FreshLoanDetailsV2Helper.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/FreshLoanDetailsV2Helper.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.helper import com.naviapp.models.response.LoanDetailsV2AdditionData @@ -12,9 +19,8 @@ object FreshLoanDetailsV2Helper { if (minTenure != null && maxTenure != null && tenureInMonths != null) { if (minTenure > 0 && maxTenure > 0 && tenureInMonths > 0 && maxTenure > minTenure) { val totalTenureValue = maxTenure - minTenure - val tenurePercentage = - tenureInMonths.toDouble() / totalTenureValue.toDouble() - if(tenurePercentage in 0.0..1.0){ + val tenurePercentage = tenureInMonths.toDouble() / totalTenureValue.toDouble() + if (tenurePercentage in 0.0..1.0) { return tenurePercentage } } @@ -22,4 +28,4 @@ object FreshLoanDetailsV2Helper { } return null } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/GetLoanV2Helper.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/GetLoanV2Helper.kt index ab738b8412..655d288e5d 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/GetLoanV2Helper.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/helper/GetLoanV2Helper.kt @@ -13,6 +13,7 @@ import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.personalloanrevamp.addressverificationrevamp.fragment.KycAddressProofV2Fragment import com.naviapp.personalloanrevamp.addressverificationrevamp.fragment.KycAddressV2Fragment import com.naviapp.personalloanrevamp.getloanRevamp.fragments.* +import com.naviapp.personalloanrevamp.getloanRevamp.fragments.InReviewV2Fragment import com.naviapp.personalloanrevamp.intermediatev2.fragments.LoanOfferUpgradeV2Fragment import com.naviapp.personalloanrevamp.kyc.fragment.KycV2Fragment import com.naviapp.personalloanrevamp.kyc.fragment.VideoKycV2Fragment diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/viewmodels/FreshLoanDetailsV2FragmentVM.kt b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/viewmodels/FreshLoanDetailsV2FragmentVM.kt index 641134d957..478034aee9 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/viewmodels/FreshLoanDetailsV2FragmentVM.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/getloanRevamp/viewmodels/FreshLoanDetailsV2FragmentVM.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.getloanRevamp.viewmodels /* @@ -26,19 +33,21 @@ import com.naviapp.personalloanrevamp.getloanRevamp.repository.LoanDetailsV2Repo import com.naviapp.personalloanrevamp.models.response.FeeDetailsV2Response import com.naviapp.utils.LOAN_APPLICATION_ID import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.launch import javax.inject.Inject +import kotlinx.coroutines.launch @HiltViewModel -class FreshLoanDetailsV2FragmentVM @Inject constructor(private val repository: LoanDetailsV2Repository) : - BaseVM() { +class FreshLoanDetailsV2FragmentVM +@Inject +constructor(private val repository: LoanDetailsV2Repository) : BaseVM() { - private val _feeDetailsV2Response = - MutableLiveData() + private val _feeDetailsV2Response = MutableLiveData() val feeDetailsV2Response: LiveData get() = _feeDetailsV2Response - private val _requestIdGenerateOffer by lazy { MutableLiveData() } + private val _requestIdGenerateOffer by lazy { + MutableLiveData() + } val requestIdGenerateOffer: LiveData get() = _requestIdGenerateOffer @@ -75,7 +84,7 @@ class FreshLoanDetailsV2FragmentVM @Inject constructor(private val repository: L val selectedLoanAmount = MutableLiveData(0.0) val selectedTenure = MutableLiveData(0) val selectedMonthlyEmi = MutableLiveData(0.0) - val selectedFirstEmiDate:MutableLiveData = MutableLiveData(null) + val selectedFirstEmiDate: MutableLiveData = MutableLiveData(null) private val loanAmountProgressPercentage = MutableLiveData(1.0) private val loanTenureProgressPercentage = MutableLiveData(1.0) @@ -144,9 +153,7 @@ class FreshLoanDetailsV2FragmentVM @Inject constructor(private val repository: L } } - fun applyLoan( - request: LoanRequest - ) { + fun applyLoan(request: LoanRequest) { viewModelScope.launch { val response = repository.applyLoan(request) if (response.error == null && response.errors.isNullOrEmpty()) { @@ -220,17 +227,15 @@ class FreshLoanDetailsV2FragmentVM @Inject constructor(private val repository: L private fun constructCacheData(data: FeeDetailsV2Response?) { data?.content?.additionalData?.loanAmountProgressPercentage = loanAmountProgressPercentage.value - val loanTenureProgressPercentage = calculateTenureProgressPercentage(data?.content?.additionalData) + val loanTenureProgressPercentage = + calculateTenureProgressPercentage(data?.content?.additionalData) loanTenureProgressPercentage?.let { - data?.content?.additionalData?.loanTenureProgressPercentage = - it - }?: run { - data?.content?.additionalData?.loanTenureProgressPercentage = - 1.0 + data?.content?.additionalData?.loanTenureProgressPercentage = it } + ?: run { data?.content?.additionalData?.loanTenureProgressPercentage = 1.0 } } fun setSelectedFirstEmiDate(firstEmiDate: String) { this.selectedFirstEmiDate.value = firstEmiDate } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/IntermediateV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/IntermediateV2Activity.kt index 342f118153..d8bb0c3164 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/IntermediateV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/IntermediateV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.intermediatev2 import android.app.Activity @@ -12,7 +19,6 @@ import com.navi.common.model.ModuleNameV2 import com.navi.common.ui.activity.BaseActivity import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.orFalse -import com.navi.common.utils.orTrue import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.common.customview.NaviHeaderView @@ -28,19 +34,19 @@ import com.naviapp.utils.EMPTY import com.naviapp.utils.IconUtils import dagger.hilt.android.AndroidEntryPoint - @AndroidEntryPoint -class IntermediateV2Activity : BaseActivity(), View.OnClickListener, - FragmentInterchangeListener, NaviHeaderView.InteractionListener { +class IntermediateV2Activity : + BaseActivity(), + View.OnClickListener, + FragmentInterchangeListener, + NaviHeaderView.InteractionListener { private lateinit var binding: ActivityIntermediateV2Binding private var currentScreen: String? = null private val helpEventTracker by lazy { NaviAnalytics.naviAnalytics.Faq() } private val sharedAggregatorVM: AggregatorSharedVM by lazy { - ViewModelProvider(this).get( - AggregatorSharedVM::class.java - ) + ViewModelProvider(this).get(AggregatorSharedVM::class.java) } override fun onCreate(savedInstanceState: Bundle?) { @@ -66,10 +72,9 @@ class IntermediateV2Activity : BaseActivity(), View.OnClickListener, } override fun navigateToNextScreen(screenTag: String, bundle: Bundle) { - val fragment = supportFragmentManager.findFragmentByTag(screenTag) - ?: IntermediateV2Helper.getFragment( - screenTag, bundle - ) + val fragment = + supportFragmentManager.findFragmentByTag(screenTag) + ?: IntermediateV2Helper.getFragment(screenTag, bundle) currentScreen = (fragment as? BaseFragment)?.screenName val fragmentTransaction = supportFragmentManager.beginTransaction() if (!supportFragmentManager.isStateSaved && !supportFragmentManager.isDestroyed) { @@ -78,7 +83,6 @@ class IntermediateV2Activity : BaseActivity(), View.OnClickListener, } } - override fun onActivityCompleted() { setResult(Activity.RESULT_OK) finish() @@ -159,5 +163,4 @@ class IntermediateV2Activity : BaseActivity(), View.OnClickListener, companion object { const val KEY_NEEDS_RESULT = "KEY_NEEDS_RESULT" } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/BankStatementV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/BankStatementV2Fragment.kt index 4de00af0c8..ce41348e00 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/BankStatementV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/BankStatementV2Fragment.kt @@ -46,13 +46,13 @@ import com.naviapp.network.ApiErrorTagType import com.naviapp.payment.models.ProviderType import com.naviapp.personalloan.getloan.bankdetails.fragments.BankDetailsFragment import com.naviapp.personalloan.getloan.bankdetails.listeners.OnSelectBankListener +import com.naviapp.personalloan.getloan.bankdetails.viewmodels.AggregatorSharedVM import com.naviapp.personalloan.intermediate.bankstatement.viewmodel.BankStatementVM import com.naviapp.personalloanrevamp.getloanRevamp.fragments.SelectBankV2Fragment import com.naviapp.personalloanrevamp.getloanRevamp.helper.GetLoanV2ViewHelper import com.naviapp.utils.* import com.naviapp.utils.Constants import com.naviapp.utils.Constants.FLOW_TYPE -import com.naviapp.utils.Constants.IS_COMING_FROM_INREVIEW_PAGE import com.naviapp.utils.Constants.IS_REVAMP_FLOW import com.naviapp.utils.Constants.OFFER_UPGRADE_FLOW import com.naviapp.utils.EMPTY @@ -200,6 +200,33 @@ class BankStatementV2Fragment : viewModel.errorResponse.observeNonNull(viewLifecycleOwner) { deInitializeAsyncListeners(firebaseDataHelper, apiPollScheduler) } + viewModel.errorAsyncResponse.observe(viewLifecycleOwner) { + when (it) { + AggregatorSharedVM.ErrorType.BANK_STATEMENT_UPLOAD_LIMIT_EXHAUSTED.name -> { + NaviDeepLinkNavigator.navigate( + activity = activity, + ctaData = CtaData( + url = NaviDeepLinkNavigator.LOAN_APPLICATION.appendStrings( + FORWARD_SLASH.toString(), + GetLoanV2ViewHelper.LOAN_OFFER_UPGRADE_V2 + ) + ), + finish = true + ) + activity?.finishAffinity() + } + AggregatorSharedVM.ErrorType.BANK_STATEMENT_SOFT_REJECT.name -> { + NaviDeepLinkNavigator.navigate( + activity = activity, + ctaData = CtaData( + url = NaviDeepLinkNavigator.ERROR_V2 + ), + finish = true + ) + activity?.finishAffinity() + } + } + } } private val onPollingEnd = { handleTimeOutError() } diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/LoanOfferUpgradeV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/LoanOfferUpgradeV2Fragment.kt index 1b16b5395c..0ed358f1d4 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/LoanOfferUpgradeV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/fragments/LoanOfferUpgradeV2Fragment.kt @@ -41,8 +41,8 @@ import com.naviapp.utils.Constants.OFFER_UPGRADE import com.naviapp.utils.Constants.OFFER_UPGRADE_FLOW import com.naviapp.utils.Constants.REPEAT_LOAN_DETAILS_FLOW -class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, - FooterViewV2.FooterInteractionListener, BackListener { +class LoanOfferUpgradeV2Fragment : + BaseFragment(), View.OnClickListener, FooterViewV2.FooterInteractionListener, BackListener { private lateinit var binding: FragmentLoanOfferUpgradeV2Binding private val viewModel by lazy { ViewModelProvider(this).get(LoanOfferUpgradeVM::class.java) } private val analyticsEventTracker = NaviAnalytics.naviAnalytics.LoanOfferUpgrade() @@ -75,22 +75,19 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, arguments?.getParcelable(Constants.KEY_CTA)?.let { it.parameters?.let { parameters -> parameters.forEach { item -> - item.key?.let { key -> - ctaQueryMap[key] = "${item.value}" - } + item.key?.let { key -> ctaQueryMap[key] = "${item.value}" } } ctaQueryMap[Constants.KEY_CURRENT_SCREEN] = GetLoanActivity.BANK_DETAILS_SCREEN } } } - private fun benefitLineItemsToItemWithTextAndIcon(benefitsLineItem: List?): List? { + private fun benefitLineItemsToItemWithTextAndIcon( + benefitsLineItem: List? + ): List? { val textWithIconList = mutableListOf() benefitsLineItem?.forEach { - val item = ItemWithTextAndIcon( - symbol = it.iconCode, - title = it.title - ) + val item = ItemWithTextAndIcon(symbol = it.iconCode, title = it.title) textWithIconList.add(item) } return textWithIconList @@ -116,15 +113,20 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, ) ) - offerUpgradeResponse.content?.popUpInfo?.let { - displayOfferDialog(it) - } + offerUpgradeResponse.content?.popUpInfo?.let { displayOfferDialog(it) } - if (!offerUpgradeResponse.content?.loanOfferBenefitCardData?.loanOfferUpgradedItems.isNullOrEmpty()) { + if ( + !offerUpgradeResponse.content + ?.loanOfferBenefitCardData + ?.loanOfferUpgradedItems + .isNullOrEmpty() + ) { binding.offerUpgradeBenefitsCardView.isVisible = true binding.boxContainer.isVisible = false binding.offerUpgradeBenefitsCardView.setProperties( - offerUpgradeResponse.content?.loanOfferBenefitCardData?.loanOfferUpgradedItemsTitle, + offerUpgradeResponse.content + ?.loanOfferBenefitCardData + ?.loanOfferUpgradedItemsTitle, offerUpgradeResponse.content?.loanOfferBenefitCardData?.loanOfferUpgradedItems, ) } else { @@ -133,13 +135,17 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, binding.boxContainer.setData( title = offerUpgradeResponse.content?.loanOfferBenefitCardData?.title, iconCode = offerUpgradeResponse.content?.loanOfferBenefitCardData?.iconCode, - subItems = benefitLineItemsToItemWithTextAndIcon(offerUpgradeResponse.content?.loanOfferBenefitCardData?.benefitsLineItem) + subItems = + benefitLineItemsToItemWithTextAndIcon( + offerUpgradeResponse.content?.loanOfferBenefitCardData?.benefitsLineItem + ) ) } offerUpgradeResponse.content?.let { offerUpgradeDetails -> context?.let { - offerUpgradeDetails.offerImprovementCardsList?.forEachIndexed { index, element -> + offerUpgradeDetails.offerImprovementCardsList?.forEachIndexed { index, element + -> if (element.verified == true) { binding.footerView.setNextButtonEnable(true) analyticsEventTracker.onOfferImprovementVerified(element.title) @@ -149,19 +155,18 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, offerImprovementCardView.setProperties(element) offerImprovementCardView.setOnClickListener { if (element.cardType == BANK_STATEMENT_CARD) { - offerUpgradeDetails.popUpInfo?.let { - displayOfferDialog(it) - } + offerUpgradeDetails.popUpInfo?.let { displayOfferDialog(it) } } analyticsEventTracker.onOfferImprovementCardClick(element.title) NaviDeepLinkNavigator.navigate( requireActivity(), ctaData = CtaData(url = element.cta?.url), - bundle = Bundle().apply { - putBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE, true) - putString(EPFO_PAGE_TYPE, OFFER_UPGRADE) - putString(FLOW_TYPE, OFFER_UPGRADE_FLOW) - } + bundle = + Bundle().apply { + putBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE, true) + putString(EPFO_PAGE_TYPE, OFFER_UPGRADE) + putString(FLOW_TYPE, OFFER_UPGRADE_FLOW) + } ) } binding.offerImprovementCardView.addView( @@ -176,9 +181,7 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, } val offerUpgradeCardList = mutableListOf() offerUpgradeResponse.content?.offerImprovementCardsList?.forEach { - it.title?.apply { - offerUpgradeCardList.add(this) - } + it.title?.apply { offerUpgradeCardList.add(this) } } analyticsEventTracker.sendOfferTypeCards(offerUpgradeCardList.toList()) } @@ -186,27 +189,29 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, private fun displayOfferDialog(popUpInfo: PopUpInfo) { analyticsEventTracker.onNoUpgradePopupShown() - val commonDialogBox = CommonDialogBox.newInstance( - screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, - title = popUpInfo.title, - description = popUpInfo.subTitle, - ctaData = popUpInfo.cta, - iconCode = popUpInfo.iconCode, - isCancelable = false - ) + val commonDialogBox = + CommonDialogBox.newInstance( + screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, + title = popUpInfo.title, + description = popUpInfo.subTitle, + ctaData = popUpInfo.cta, + iconCode = popUpInfo.iconCode, + isCancelable = false + ) safelyShowDialogBox(commonDialogBox, CommonDialogBox.TAG) } private fun displayOfferDialog(offerUpgradeGreetingResponse: OfferUpgradeGreetingResponse) { analyticsEventTracker.onNoUpgradePopupShown() - val commonDialogBox = CommonDialogBox.newInstance( - screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, - title = offerUpgradeGreetingResponse.title, - description = offerUpgradeGreetingResponse.description, - ctaData = offerUpgradeGreetingResponse.nextCta, - iconCode = offerUpgradeGreetingResponse.iconCode, - isCancelable = false - ) + val commonDialogBox = + CommonDialogBox.newInstance( + screenName = NaviAnalytics.NO_UPGRADE_OFFER_DIALOG, + title = offerUpgradeGreetingResponse.title, + description = offerUpgradeGreetingResponse.description, + ctaData = offerUpgradeGreetingResponse.nextCta, + iconCode = offerUpgradeGreetingResponse.iconCode, + isCancelable = false + ) safelyShowDialogBox(commonDialogBox, CommonDialogBox.TAG) } @@ -236,46 +241,27 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, } override fun onFooterBackPressed(backCta: CtaData?) { - backCta?.url?.let { - listener?.navigateTo( - it - ) - } + backCta?.url?.let { listener?.navigateTo(it) } } override fun onFooterNextPressed(nextCta: CtaData?) { analyticsEventTracker.onNextButtonClick() NaviTrackEvent.setStartTs(screenName) - nextCta?.url?.let { - listener?.navigateTo( - it - ) - } + nextCta?.url?.let { listener?.navigateTo(it) } } override fun onBackPressed() { - when(arguments?.getString(FLOW_TYPE).orEmpty()){ - + when (arguments?.getString(FLOW_TYPE).orEmpty()) { REPEAT_LOAN_DETAILS_FLOW -> { - listener?.navigateTo( - GetLoanV2ViewHelper.LOAN_DETAILS_V2_FRAGMENT, - Bundle() - ) + listener?.navigateTo(GetLoanV2ViewHelper.LOAN_DETAILS_V2_FRAGMENT, Bundle()) } FRESH_LOAN_DETAILS_FLOW -> { - listener?.navigateTo( - GetLoanV2ViewHelper.FRESH_LOAN_DETAILS_V2, - Bundle() - ) + listener?.navigateTo(GetLoanV2ViewHelper.FRESH_LOAN_DETAILS_V2, Bundle()) } else -> { - listener?.navigateTo( - NaviDeepLinkNavigator.HOME, - Bundle() - ) + listener?.navigateTo(NaviDeepLinkNavigator.HOME, Bundle()) } } - } override val screenName: String @@ -286,9 +272,7 @@ class LoanOfferUpgradeV2Fragment : BaseFragment(), View.OnClickListener, const val BANK_STATEMENT_CARD = "BANK_STATEMENT" fun newInstance(bundle: Bundle?): LoanOfferUpgradeV2Fragment { - return LoanOfferUpgradeV2Fragment().apply { - arguments = bundle - } + return LoanOfferUpgradeV2Fragment().apply { arguments = bundle } } } } diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/helper/IntermediateV2Helper.kt b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/helper/IntermediateV2Helper.kt index 590df313f6..3530c10671 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/helper/IntermediateV2Helper.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/intermediatev2/helper/IntermediateV2Helper.kt @@ -1,15 +1,21 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.intermediatev2.helper import android.os.Bundle import androidx.fragment.app.Fragment -import com.naviapp.personalloanrevamp.getloanRevamp.fragments.GstVerificationV2Fragment import com.naviapp.personalloanrevamp.getloanRevamp.fragments.GstVerificationPasswordV2Fragment -import com.naviapp.personalloanrevamp.intermediatev2.fragments.TelcoOtpV2Fragment +import com.naviapp.personalloanrevamp.getloanRevamp.fragments.GstVerificationV2Fragment import com.naviapp.personalloanrevamp.intermediatev2.fragments.BankStatementV2Fragment +import com.naviapp.personalloanrevamp.intermediatev2.fragments.TelcoOtpV2Fragment import com.naviapp.personalloanrevamp.useridentificationv2.fragments.EmploymentOtpVerificationFragment import com.naviapp.personalloanrevamp.useridentificationv2.fragments.EmploymentVerificationV2Fragment - object IntermediateV2Helper { private const val GST_VERIFICATION_V2 = "GST_VERIFICATION_V2" @@ -50,4 +56,4 @@ object IntermediateV2Helper { else -> "" } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/activity/KycDocumentCaptureV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/activity/KycDocumentCaptureV2Activity.kt index ace7ff7a22..1f6597d84b 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/activity/KycDocumentCaptureV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/activity/KycDocumentCaptureV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.kyc.activity import android.Manifest @@ -16,8 +23,8 @@ import androidx.core.app.ActivityCompat import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import androidx.lifecycle.MutableLiveData -import com.navi.base.model.CtaData import androidx.lifecycle.ViewModelProvider +import com.navi.base.model.CtaData import com.navi.common.managers.PermissionsManager import com.navi.common.model.ModuleNameV2 import com.navi.common.ui.activity.BaseActivity @@ -45,14 +52,20 @@ import com.otaliastudios.cameraview.controls.Flash import com.otaliastudios.cameraview.controls.Preview import com.otaliastudios.cameraview.size.SizeSelectors -class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View.OnClickListener, - FooterViewV2.FooterInteractionListener, NaviHeaderView.InteractionListener { +class KycDocumentCaptureV2Activity : + BaseActivity(), + CameraActionListener, + View.OnClickListener, + FooterViewV2.FooterInteractionListener, + NaviHeaderView.InteractionListener { private lateinit var binding: KycDocumentUploadV2ActivityBinding private val captureImageBitmap = MutableLiveData() private val permissionsManager by lazy { PermissionsManager(this) } private val cameraPermission by lazy { arrayOf(Manifest.permission.CAMERA) } private val cameraListener = CameraEventListener(this) - private val storagePermission by lazy { arrayOf(PermissionsManager.READ_EXTERNAL_STORAGE_PERMISSION) } + private val storagePermission by lazy { + arrayOf(PermissionsManager.READ_EXTERNAL_STORAGE_PERMISSION) + } private var currentScreen: String = NaviAnalytics.KYC_DOCUMENT_CAPTURE_SCREEN private val viewModel by lazy { ViewModelProvider(this).get(AddressVerificationVM::class.java) } @@ -83,19 +96,13 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. binding.headerView.setOnInteractionListener(this) - binding.footerView.setProperties( - documentTypeView.footer, - this - ) + binding.footerView.setProperties(documentTypeView.footer, this) binding.footerView.showDataSafetyHeader() binding.footerView.binding.knowMoreTv.setOnClickListener { documentTypeView.content?.let { val infoBottomSheet = InformationBottomSheet.getInstance(it) - safelyShowBottomSheet( - infoBottomSheet, - InformationBottomSheet.TAG - ) + safelyShowBottomSheet(infoBottomSheet, InformationBottomSheet.TAG) } } } @@ -145,10 +152,10 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. binding.ivFlash.setOnClickListener { if (binding.camera.flash == Flash.OFF) { binding.camera.flash = Flash.ON - Toast.makeText(this, R.string.flash_on , Toast.LENGTH_SHORT).show() + Toast.makeText(this, R.string.flash_on, Toast.LENGTH_SHORT).show() } else { binding.camera.flash = Flash.OFF - Toast.makeText(this, R.string.flash_off , Toast.LENGTH_SHORT).show() + Toast.makeText(this, R.string.flash_off, Toast.LENGTH_SHORT).show() } } @@ -158,8 +165,8 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. } private fun handleDocumentUploadFromDevice() { - if (permissionsManager.hasPermissions(storagePermission) - ) openStorage() else + if (permissionsManager.hasPermissions(storagePermission)) openStorage() + else permissionsManager.requestPermissions( storagePermission, PermissionsManager.REQUEST_CODE @@ -167,10 +174,7 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. } private fun openStorage() { - val galleryIntent = Intent( - Intent.ACTION_PICK, - MediaStore.Images.Media.EXTERNAL_CONTENT_URI - ) + val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) galleryIntent.type = "image/*" resultLauncher.launch(galleryIntent) } @@ -187,17 +191,15 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. } private fun displayImageFromGallery(uri: Uri) { - val bitmap = BitmapFactory.decodeStream( - contentResolver.openInputStream(uri) - ) + val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri)) captureImageBitmap.value = bitmap } private fun init() { initBeforeScreenCapture() observeCameraImage() - if (permissionsManager.hasPermissions(cameraPermission)) initializeCamera() else - permissionsManager.requestPermissions(cameraPermission) + if (permissionsManager.hasPermissions(cameraPermission)) initializeCamera() + else permissionsManager.requestPermissions(cameraPermission) } private fun initializeCamera() { @@ -208,9 +210,7 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. private fun observeCameraImage() { captureImageBitmap.observeNullable(this) { bitmap -> - bitmap?.let { - initAfterScreenCapture(bitmap) - } + bitmap?.let { initAfterScreenCapture(bitmap) } } } @@ -277,9 +277,11 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. currentImageSelectorMode = CAMERA_MODE init() } - R.id.camera_capture_iv -> if (permissionsManager.hasPermissions(cameraPermission)) capturePicture() else - permissionsManager.requestPermissions(cameraPermission) - R.id.camera_action_button -> captureImageBitmap.value?.let { handleAfterCaptureImage(it) } + R.id.camera_capture_iv -> + if (permissionsManager.hasPermissions(cameraPermission)) capturePicture() + else permissionsManager.requestPermissions(cameraPermission) + R.id.camera_action_button -> + captureImageBitmap.value?.let { handleAfterCaptureImage(it) } R.id.back_iv -> onBackButtonClicked() } } @@ -295,9 +297,7 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. return } closeCamera() - getCameraCaptureImageBitmap( - result, captureImageBitmap - ) + getCameraCaptureImageBitmap(result, captureImageBitmap) } } @@ -311,8 +311,9 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. when (permission) { PermissionsManager.CAMERA_PERMISSION -> { if (onGrantPermission()) return initializeCamera() - if (!binding.permissionDeniedView.isVisible && - isDontAskAgainClicked(permissions.first(), grantResults.first()) + if ( + !binding.permissionDeniedView.isVisible && + isDontAskAgainClicked(permissions.first(), grantResults.first()) ) { binding.permissionDeniedView.visibility = View.VISIBLE binding.cameraCaptureIv.visibility = View.INVISIBLE @@ -343,7 +344,7 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. private fun isDontAskAgainClicked(permission: String, grantResult: Int): Boolean { return !ActivityCompat.shouldShowRequestPermissionRationale(this, permission) && - grantResult == PackageManager.PERMISSION_DENIED + grantResult == PackageManager.PERMISSION_DENIED } override fun onCameraError(exception: CameraException?) { @@ -372,5 +373,4 @@ class KycDocumentCaptureV2Activity : BaseActivity(), CameraActionListener, View. override fun onFooterNextPressed(nextCta: CtaData?) { captureImageBitmap.value?.let { handleAfterCaptureImage(it) } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/adapter/MultipleKycItemAdapter.kt b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/adapter/MultipleKycItemAdapter.kt index 042fd6bb20..5aa72f5811 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/adapter/MultipleKycItemAdapter.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/adapter/MultipleKycItemAdapter.kt @@ -40,13 +40,15 @@ class MultipleKycItemAdapter( kycItem.description?.iconCode?.let { holder.binding.tvKycDescription.setCompoundDrawablesWithIntrinsicBounds( - IconUtils.getIconResourceId(it), 0, 0, 0 - ) - } ?: run { - holder.binding.tvKycDescription.setCompoundDrawablesWithIntrinsicBounds( - 0, 0, 0, 0 + IconUtils.getIconResourceId(it), + 0, + 0, + 0 ) } + ?: run { + holder.binding.tvKycDescription.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + } if (position != kycItemList.size - 1) { holder.binding.dividerOr.visibility = View.VISIBLE @@ -62,9 +64,7 @@ class MultipleKycItemAdapter( onCheckChanged(kycItemList[position], position) } - holder.binding.root.setOnClickListener { - onCheckChanged(kycItemList[position], position) - } + holder.binding.root.setOnClickListener { onCheckChanged(kycItemList[position], position) } if (kycItemList[position].selected) { if (kycItemList[position].kycType == KycItemType.VIDEO_KYC.name) { @@ -85,9 +85,7 @@ class MultipleKycItemAdapter( } private fun changeSelection(position: Int) { - kycItemList.forEach { - it.selected = false - } + kycItemList.forEach { it.selected = false } kycItemList[position].selected = true notifyDataSetChanged() } @@ -95,11 +93,7 @@ class MultipleKycItemAdapter( override fun getItemCount(): Int { return kycItemList.size } - - } class KycItemRadioButtonViewHolder(val binding: ItemRadioButtonForMultipleKycItemBinding) : RecyclerView.ViewHolder(binding.root) - - diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/fragment/VideoKycV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/fragment/VideoKycV2Fragment.kt index a72307b545..c67fae5807 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/kyc/fragment/VideoKycV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/kyc/fragment/VideoKycV2Fragment.kt @@ -9,6 +9,7 @@ package com.naviapp.personalloanrevamp.kyc.fragment import android.Manifest import android.content.Context +import android.content.Intent import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri @@ -29,8 +30,11 @@ import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.CtaData import com.navi.common.firebasedb.* import com.navi.common.managers.PermissionsManager +import com.navi.common.model.ModuleName import com.navi.common.ui.fragment.BaseFragment import com.navi.common.utils.* +import com.navi.navi_vkyc.presentation.activity.VKYCActivity +import com.naviapp.BuildConfig import com.naviapp.R import com.naviapp.analytics.neoeyed.viewmodel.NeoEyedVM import com.naviapp.analytics.utils.LoadTimeEventTracker @@ -130,6 +134,8 @@ class VideoKycV2Fragment : viewModel.videoKycDetailsLiveDataV2.observeNonNull(this) { kycDetailsResponse -> hideLoader() + analyticsEventTracker.onLandedOnPanPage() + kycDetailsResponse.header?.title?.let { headerListener?.setProperties( title = it, @@ -141,6 +147,7 @@ class VideoKycV2Fragment : if (kycDetailsResponse.videoKycDetails?.isFooterEnabled?.orFalse() == true) { binding.footerView.visibility = View.GONE binding.actionConnectNow.visibility = View.VISIBLE + kycDetailsResponse.videoKycDetails.kycItemList?.get(0)?.selected = false binding.actionConnectNow.setProperties( title = kycDetailsResponse.footer?.nextCta?.title ) @@ -253,10 +260,27 @@ class VideoKycV2Fragment : binding.actionConnectNow.setOnClickListener { analyticsEventTracker.onConnectNowVkycClicked() NaviTrackEvent.setStartTs(screenName) - videoKycInit() + if ( + viewModel.videoKycDetailsLiveDataV2.value?.videoKycDetails?.vendor == + com.navi.navi_vkyc.common.Constants.VKYC_VENDOR_NAME + ) { + inHouseVKYCInit() + } else { + videoKycInit() + } } } + private fun inHouseVKYCInit() { + val intent = Intent(activity, VKYCActivity::class.java) + intent.putExtra( + com.navi.navi_vkyc.common.Constants.APPLICATION_ID, + BuildConfig.APPLICATION_ID + ) + intent.putExtra(com.navi.navi_vkyc.common.Constants.MODULE_NAME, ModuleName.LE.name) + activity?.startActivity(intent) + } + private fun videoKycInit() { if ( permissionsManager.hasPermissions( @@ -619,6 +643,7 @@ class VideoKycV2Fragment : override fun onAadhaarOtpOptionTap() {} override fun onPanItemTap() { + analyticsEventTracker.onPanVkycClicked() analyticsEventTracker.onVkycItemClicked(KycItemType.PAN.name) viewModel.setCurrentSelectedType(KycItemType.PAN.name) if (isPermissionGranted()) { diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/models/KycListItem.kt b/app/src/main/java/com/naviapp/personalloanrevamp/models/KycListItem.kt index 42855ce510..14efa6ba83 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/models/KycListItem.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/models/KycListItem.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.models import android.graphics.Bitmap @@ -13,41 +20,27 @@ data class KycDetailsResponseV2( ) data class KycStatusDetailsV2( - @SerializedName("kycDetailsComplete") - val kycDetailsComplete: Boolean, - @SerializedName("kycItemList") - val kycItemList: List? = null, - @SerializedName("dataSafetyBottomSheet") val dataSafetyBottomSheet: InfoBottomSheetConfig? = null + @SerializedName("kycDetailsComplete") val kycDetailsComplete: Boolean, + @SerializedName("kycItemList") val kycItemList: List? = null, + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null ) data class KycItemV2( - @SerializedName("clickable") - val clickable: Boolean = false, - @SerializedName("description") - var description: StyledTextWithIconCode? = null, - @SerializedName("instruction") - var instruction: List? = null, - @SerializedName("items") - val items: List? = null, - @SerializedName("type") - val kycType: String? = null, - @SerializedName("leftIconCode") - val leftIconCode: String? = null, - @SerializedName("rightIconCode") - val rightIconCode: String? = null, - @SerializedName("selected") - var selected: Boolean = false, - @SerializedName("status") - val status: String? = null, - @SerializedName("title") - val title: String? = null, - @SerializedName("widgetType") - val widgetType: String? = null, - @SerializedName("itemFooter") - val itemFooter: ItemFooter? + @SerializedName("clickable") val clickable: Boolean = false, + @SerializedName("description") var description: StyledTextWithIconCode? = null, + @SerializedName("instruction") var instruction: List? = null, + @SerializedName("items") val items: List? = null, + @SerializedName("type") val kycType: String? = null, + @SerializedName("leftIconCode") val leftIconCode: String? = null, + @SerializedName("rightIconCode") val rightIconCode: String? = null, + @SerializedName("selected") var selected: Boolean = false, + @SerializedName("status") val status: String? = null, + @SerializedName("title") val title: String? = null, + @SerializedName("widgetType") val widgetType: String? = null, + @SerializedName("itemFooter") val itemFooter: ItemFooter? ) { - @Transient - var selfieImageBitmap: Bitmap? = null + @Transient var selfieImageBitmap: Bitmap? = null } enum class KycMultipleActionType { @@ -56,15 +49,11 @@ enum class KycMultipleActionType { } data class ItemFooter( - @SerializedName("backgroundColor") - val hexColor: String? = null, - @SerializedName("text") - val text: String? = null + @SerializedName("backgroundColor") val hexColor: String? = null, + @SerializedName("text") val text: String? = null ) data class Instruction( - @SerializedName("iconCode") - val iconCode: String? = null, - @SerializedName("title") - val title: String? = null -) \ No newline at end of file + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("title") val title: String? = null +) diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/models/RewardsWidgetConfig.kt b/app/src/main/java/com/naviapp/personalloanrevamp/models/RewardsWidgetConfig.kt index a556b74abf..238bff701f 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/models/RewardsWidgetConfig.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/models/RewardsWidgetConfig.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.models import com.google.gson.annotations.SerializedName @@ -10,10 +17,8 @@ import com.navi.naviwidgets.models.response.TagInfo import com.naviapp.models.response.WidgetConfig import java.io.Serializable - data class RewardsWidgetConfig( - @SerializedName("body") - val widgetData: RewardsInfoWidgetData? = null, + @SerializedName("body") val widgetData: RewardsInfoWidgetData? = null, ) : WidgetConfig(), Serializable, RewardsInfoWidgetInfo { companion object { @@ -39,4 +44,4 @@ data class RewardsWidgetConfig( override fun rewardType(): String? { return widgetData?.rewardType } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/models/VideoKycDetailsV2.kt b/app/src/main/java/com/naviapp/personalloanrevamp/models/VideoKycDetailsV2.kt index ce36f5356c..17cbbd41ee 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/models/VideoKycDetailsV2.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/models/VideoKycDetailsV2.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.models import com.google.gson.annotations.SerializedName @@ -5,7 +12,6 @@ import com.naviapp.models.Note import com.naviapp.models.response.Footer import com.naviapp.models.response.Header - data class VideoKycDetailsV2Response( @SerializedName("header") val header: Header? = null, @SerializedName("content") val videoKycDetails: VideoKycDetailsV2? = null, @@ -16,11 +22,12 @@ data class VideoKycDetailsV2( @SerializedName("bookedSlot") val bookedSlot: BookedSlotV2? = null, @SerializedName("note") val note: Note? = null, @SerializedName("isFooterEnabled") val isFooterEnabled: Boolean? = null, - @SerializedName("kycItemsV2") val kycItemList: List? = null + @SerializedName("kycItemsV2") val kycItemList: List? = null, + @SerializedName("vendor") val vendor: String? = null ) data class BookedSlotV2( @SerializedName("title") val title: String? = null, @SerializedName("iconCode") val iconCode: String? = null, @SerializedName("slotStartTimeInMiliSec") val slotStartTimeInMiliSec: Long? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/models/response/PersonalLoanTrackerResponse.kt b/app/src/main/java/com/naviapp/personalloanrevamp/models/response/PersonalLoanTrackerResponse.kt index 776e47cd7f..777a0ddfc8 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/models/response/PersonalLoanTrackerResponse.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/models/response/PersonalLoanTrackerResponse.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.models.response import android.os.Parcelable @@ -5,7 +12,6 @@ import com.google.gson.annotations.SerializedName import com.navi.naviwidgets.models.response.RewardsInfoWidget import com.naviapp.models.response.Footer import com.naviapp.models.response.Header -import com.naviapp.models.response.RewardsInfo import kotlinx.android.parcel.Parcelize data class PersonalLoanTrackerResponse( @@ -32,4 +38,4 @@ data class TagContent( @SerializedName("text") val text: String? = null, @SerializedName("bgColor") val bgColor: String? = null, @SerializedName("textColor") val textColor: String? = null -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/LoanEligibilityLoaderV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/LoanEligibilityLoaderV2Activity.kt index a868224db8..0097143a4c 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/LoanEligibilityLoaderV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/LoanEligibilityLoaderV2Activity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.useridentificationv2.activities import android.animation.Animator @@ -44,22 +51,17 @@ import com.naviapp.utils.Constants.OFFER_GENERATION_FLOW import com.naviapp.utils.Constants.SUCCESS_ANIMATION_GREEN_BG_TIME import com.naviapp.utils.Constants.SUCCESS_ANIMATION_WHITE_BG_TIME - class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { private lateinit var binding: ActivityLoanEligibilityLoaderV2Binding private var apiPollScheduler: ApiPollScheduler? = null - private val loanDetailsVM by lazy { - ViewModelProvider(this).get(LoanDetailsVM::class.java) - } + private val loanDetailsVM by lazy { ViewModelProvider(this).get(LoanDetailsVM::class.java) } private val userDataViewModel by lazy { ViewModelProvider(this).get(UserDataViewModel::class.java) } private val permissionViewModel by lazy { ViewModelProvider(this).get(PermissionViewModel::class.java) } - private val neoEyedVM by lazy { - ViewModelProvider(this).get(NeoEyedVM::class.java) - } + private val neoEyedVM by lazy { ViewModelProvider(this).get(NeoEyedVM::class.java) } private var loanOfferType: String? = null private var offerImprovementChannelType: ArrayList? = null private var firebaseDataHelper: FirebaseDataHelper? = null @@ -73,11 +75,12 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { super.setContentView(binding.root) NaviTrackEvent.sendScreenTransitionEvent(screenName) initData() - initError(loanDetailsVM,actions = listOf( - Pair( - handlePanDetailsFailedFromCibil, ApiErrorTagType.INVALID_PAN_DETAILS - ) - ), actionErrorV2Enabled = true) + initError( + loanDetailsVM, + actions = + listOf(Pair(handlePanDetailsFailedFromCibil, ApiErrorTagType.INVALID_PAN_DETAILS)), + actionErrorV2Enabled = true + ) initError(permissionViewModel, actionErrorV2Enabled = true) perfUtils.startNewRelicInteraction(NewrelicConstants.USER_DATA_LOAD) sendUserData() @@ -97,11 +100,8 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { private fun initError() { initError( viewModel = loanDetailsVM, - actions = listOf( - Pair( - handlePanDetailsFailedFromCibil, ApiErrorTagType.INVALID_PAN_DETAILS - ) - ), + actions = + listOf(Pair(handlePanDetailsFailedFromCibil, ApiErrorTagType.INVALID_PAN_DETAILS)), actionErrorV2Enabled = true ) } @@ -161,7 +161,8 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { val bundle = Bundle() bundle.putBoolean(IntermediateActivity.KEY_NEEDS_RESULT, false) NaviDeepLinkNavigator.navigate(this, ctaData, true, bundle) - } ?: loanDetailsVM.generateOffer(loanOfferType, offerImprovementChannelType) + } + ?: loanDetailsVM.generateOffer(loanOfferType, offerImprovementChannelType) perfUtils.sendEventWithTimeStamp( NewrelicConstants.PRE_ELIGIBILITY_CTA_SUCCESS, screenName @@ -180,7 +181,7 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { it?.let { fetchOfferIdAndStopApiPoll(it) } } loanDetailsVM.generateOfferFailed.observeNonNull(this) { -// binding.loader.pause() + // binding.loader.pause() statusHandling(it) } @@ -202,7 +203,9 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { ScreenNavigator.INTERMEDIATE_SCREEN_V2, bundle ) - loadTimeEventTracker.onLoadingCompleted(NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME) + loadTimeEventTracker.onLoadingCompleted( + NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME + ) return@observeNonNull } if (offerIdResponse.details?.isRejected == true) { @@ -210,13 +213,16 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { return@observeNonNull } else if (offerIdResponse.details?.isCibilFailure == true) { NaviDeepLinkNavigator.navigate( - this, CtaData( - url = NaviDeepLinkNavigator.INTERMEDIATE.plus( - Constants.DIVIDER - ).plus(SubPageStatusType.CIBIL_FAILURE) + this, + CtaData( + url = + NaviDeepLinkNavigator.INTERMEDIATE.plus(Constants.DIVIDER) + .plus(SubPageStatusType.CIBIL_FAILURE) ) ) - loadTimeEventTracker.onLoadingCompleted(NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME) + loadTimeEventTracker.onLoadingCompleted( + NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME + ) return@observeNonNull } else if (offerIdResponse.details?.showCibilTimeoutLoader.orFalse()) { handleCibilTimeoutError() @@ -248,13 +254,15 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { bundle.putString(ErrorActivity.IS_SOFT_REJECT, Constants.TRUE) } if (it.success.orFalse()) { - bundle.putBoolean(IS_UW_REJECTION , true) + bundle.putBoolean(IS_UW_REJECTION, true) perfUtils.sendEventWithTimeStamp(NewrelicConstants.LOAN_REJECTED, screenName) analyticsEventTracker.trackUserDuration( userDataViewModel.getUserDurationInSeconds(), "Loan Rejected" ) - loadTimeEventTracker.onLoadingCompleted(NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME) + loadTimeEventTracker.onLoadingCompleted( + NaviAnalytics.PL_LOAN_ELIGIBILITY_LOADER_TIME + ) ScreenNavigator.instance.startActivityWithNoActivityStack( this, ScreenNavigator.ERROR_FULL_PAGE_SCREEN_V2, @@ -273,29 +281,25 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } private fun firebaseInitPreEligibility(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - it.status?.run { - onPreEligibilityResponse( - this, - false, - requestId - ) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { + it.status?.run { onPreEligibilityResponse(this, false, requestId) } } } } - } firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - PRE_ELIGIBILITY, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + PRE_ELIGIBILITY, + requestId, + notificationPath + ) + } } private fun onPreEligibilityResponse( @@ -329,13 +333,15 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } private fun apiPollInitPermission(uploadDataAsyncResponse: UploadDataAsyncResponse) { - apiPollScheduler = ApiPollScheduler( - numberOfRetry = uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue( - NUMBER_OF_RETRY - ) - ) { - permissionViewModel.fetchAsyncRequestData(uploadDataAsyncResponse.requestId.orEmpty()) - } + apiPollScheduler = + ApiPollScheduler( + numberOfRetry = + uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue(NUMBER_OF_RETRY) + ) { + permissionViewModel.fetchAsyncRequestData( + uploadDataAsyncResponse.requestId.orEmpty() + ) + } apiPollScheduler?.scheduleApiPoll() permissionViewModel.dataAsyncResponse.observeNonNull(this) { onPermissionSubmissionResponse( @@ -346,23 +352,25 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } private fun firebaseInitPermission(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { - onPermissionSubmissionResponse(it.status, false, requestId) + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { + onPermissionSubmissionResponse(it.status, false, requestId) + } } } - } firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - PERMISSION, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + PERMISSION, + requestId, + notificationPath + ) + } } private fun onPermissionSubmissionResponse( @@ -416,9 +424,9 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { private fun apiPollInit(uploadDataAsyncResponse: UploadDataWithCtaAsyncResponse, type: String) { apiPollScheduler = - ApiPollScheduler(numberOfRetry = uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue( - NUMBER_OF_RETRY - ), + ApiPollScheduler( + numberOfRetry = + uploadDataAsyncResponse.requestConfig?.numOfRetries.orValue(NUMBER_OF_RETRY), doOnTimeout = { if (type == PRE_ELIGIBILITY) { perfUtils.sendEventWithTimeStamp( @@ -430,7 +438,8 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } else { runOnUiThread { handleTimeOutError() } } - }) { + } + ) { perfUtils.startNewRelicInteraction(type) analyticsEventTracker.sendEventWithTimeStamp(type + "_start_time") loanDetailsVM.checkApiPollStatus(uploadDataAsyncResponse.requestId.orEmpty(), type) @@ -440,21 +449,23 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { private fun firebaseInit(requestId: String, notificationPath: String) { - firebaseDataReceiveListener = object : FirebaseDataReceiveListener { - override fun onDataReceive(firebaseResponse: FirebaseResponse?) { - firebaseResponse?.let { it.status?.run { fetchOfferIdAndStopApiPoll(this) } } + firebaseDataReceiveListener = + object : FirebaseDataReceiveListener { + override fun onDataReceive(firebaseResponse: FirebaseResponse?) { + firebaseResponse?.let { it.status?.run { fetchOfferIdAndStopApiPoll(this) } } + } } - } firebaseDataHelper = null - firebaseDataHelper = FirebaseDataHelper().apply { - initFirebaseDataReceiver( - lifecycle, - firebaseDataReceiveListener, - OFFER_GENERATE, - requestId, - notificationPath - ) - } + firebaseDataHelper = + FirebaseDataHelper().apply { + initFirebaseDataReceiver( + lifecycle, + firebaseDataReceiveListener, + OFFER_GENERATE, + requestId, + notificationPath + ) + } } private fun fetchOfferIdAndStopApiPoll( @@ -484,7 +495,7 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { "Loan Rejected" ) val data = Bundle() - data.putBoolean(IS_UW_REJECTION , true) + data.putBoolean(IS_UW_REJECTION, true) data.putString(Constants.WIDGET_ID, Constants.PERSONAL_LOAN) ScreenNavigator.instance.startActivityWithNoActivityStack( this, @@ -496,8 +507,9 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } private fun statusHandling(status: String) { - if (TextUtils.equals(status, FirebaseStatusType.SUCCESS) - || TextUtils.equals(status, FirebaseStatusType.FAILURE) + if ( + TextUtils.equals(status, FirebaseStatusType.SUCCESS) || + TextUtils.equals(status, FirebaseStatusType.FAILURE) ) { deInitializeAsyncListeners() apiPollScheduler?.stopApiPoll() @@ -532,28 +544,26 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { ) if (loanDetailsVM.offerIdResponse.value?.details?.redirectCtaUrl.isNotNull()) { val url = loanDetailsVM.offerIdResponse.value?.details?.redirectCtaUrl - NaviDeepLinkNavigator.navigate( - activity = this, - ctaData = CtaData(url = url) - ) + NaviDeepLinkNavigator.navigate(activity = this, ctaData = CtaData(url = url)) return } loanDetailsVM.requestIdGenerateOffer.value?.data?.intermediateCta?.let { data.putString(FLOW_TYPE, OFFER_GENERATION_FLOW) NaviDeepLinkNavigator.navigate(this, it, true, data) - } ?: run { - perfUtils.sendEventWithTimeStamp(NewrelicConstants.LOAN_APPROVED, screenName) - analyticsEventTracker.trackUserDuration( - userDataViewModel.getUserDurationInSeconds(), - "Loan Approved" - ) - ScreenNavigator.instance.startActivityWithNoActivityStack( - this, - ScreenNavigator.GEL_LOAN_SCREEN, - data - ) } + ?: run { + perfUtils.sendEventWithTimeStamp(NewrelicConstants.LOAN_APPROVED, screenName) + analyticsEventTracker.trackUserDuration( + userDataViewModel.getUserDurationInSeconds(), + "Loan Approved" + ) + ScreenNavigator.instance.startActivityWithNoActivityStack( + this, + ScreenNavigator.GEL_LOAN_SCREEN, + data + ) + } } private fun observeOfferGenerateComplitionAPI() { @@ -564,20 +574,21 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { } } - private val handlePanDetailsFailedFromCibil: View.OnClickListener = View.OnClickListener { - loanDetailsVM.getPanFailedRedirectUrl()?.let { url -> - perfUtils.sendEventWithTimeStamp(NewrelicConstants.PAN_CIBIL_FAILED, screenName) - analyticsEventTracker.trackUserDuration( - userDataViewModel.getUserDurationInSeconds(), - "PAN CIBIL Failed" - ) - NaviDeepLinkNavigator.navigate( - activity = this, - ctaData = CtaData(url = url), - finish = true - ) + private val handlePanDetailsFailedFromCibil: View.OnClickListener = + View.OnClickListener { + loanDetailsVM.getPanFailedRedirectUrl()?.let { url -> + perfUtils.sendEventWithTimeStamp(NewrelicConstants.PAN_CIBIL_FAILED, screenName) + analyticsEventTracker.trackUserDuration( + userDataViewModel.getUserDurationInSeconds(), + "PAN CIBIL Failed" + ) + NaviDeepLinkNavigator.navigate( + activity = this, + ctaData = CtaData(url = url), + finish = true + ) + } } - } override fun onDestroy() { if (userDataViewModel.shouldFireDurationEvent()) { @@ -595,17 +606,29 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { loanDetailsVM.offerGenerateStatus() } - private fun startAnimationGreenBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.green)) - startAnimationWhiteBackground() - }, SUCCESS_ANIMATION_WHITE_BG_TIME) + private fun startAnimationGreenBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.green) + ) + startAnimationWhiteBackground() + }, + SUCCESS_ANIMATION_WHITE_BG_TIME + ) } - private fun startAnimationWhiteBackground(){ - Handler(Looper.getMainLooper()).postDelayed({ - binding.successAnimationHolderFl.setBackgroundColor(ContextCompat.getColor(this,R.color.white)) - }, SUCCESS_ANIMATION_GREEN_BG_TIME) + private fun startAnimationWhiteBackground() { + Handler(Looper.getMainLooper()) + .postDelayed( + { + binding.successAnimationHolderFl.setBackgroundColor( + ContextCompat.getColor(this, R.color.white) + ) + }, + SUCCESS_ANIMATION_GREEN_BG_TIME + ) } private fun handleSuccessAnimation() { @@ -614,17 +637,16 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { binding.loaderAnimation.visibility = View.GONE binding.loaderSuccessAnimation.playAnimation() startAnimationGreenBackground() - binding.loaderSuccessAnimation.addAnimatorListener(object : Animator.AnimatorListener { - override fun onAnimationStart(p0: Animator?) { + binding.loaderSuccessAnimation.addAnimatorListener( + object : Animator.AnimatorListener { + override fun onAnimationStart(p0: Animator?) {} + override fun onAnimationEnd(p0: Animator?) { + navigateToNextScreen() + } + override fun onAnimationCancel(p0: Animator?) {} + override fun onAnimationRepeat(p0: Animator?) {} } - override fun onAnimationEnd(p0: Animator?) { - navigateToNextScreen() - } - override fun onAnimationCancel(p0: Animator?) { - } - override fun onAnimationRepeat(p0: Animator?) { - } - }) + ) } override val screenName: String @@ -643,4 +665,4 @@ class LoanEligibilityLoaderV2Activity : WifiTrackerBaseActivity() { private const val AMOUNT_VIEW_ANIMATION_DELAY = 500L private const val NEXT_SCREEN_TRANSITION_DELAY = AMOUNT_VIEW_ANIMATION_DELAY + 1000L } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/PermissionV2Activity.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/PermissionV2Activity.kt index b55fe375ed..ba3108074b 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/PermissionV2Activity.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/activities/PermissionV2Activity.kt @@ -55,9 +55,10 @@ import com.naviapp.personalloanrevamp.useridentificationv2.adapter.PermissionV2A import com.naviapp.personalloanrevamp.useridentificationv2.fragments.InformationBottomSheet import com.naviapp.receiver.WifiTrackerBaseActivity import com.naviapp.registration.viewmodel.RegistrationVM -import com.naviapp.utils.* import com.naviapp.utils.Constants import com.naviapp.utils.Constants.REDIRECT_PAGE_STATUS +import com.naviapp.utils.IntentConstants +import com.naviapp.utils.getProviderConfig class PermissionV2Activity : WifiTrackerBaseActivity(), diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/adapter/PermissionV2Adapter.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/adapter/PermissionV2Adapter.kt index 037191d443..f0e87a7a03 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/adapter/PermissionV2Adapter.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/adapter/PermissionV2Adapter.kt @@ -12,9 +12,9 @@ import android.content.pm.PackageManager import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.navi.common.model.permission.PermissionTile import com.navi.common.utils.setShakeAnimation import com.naviapp.databinding.PermissionTypeLayoutBinding -import com.naviapp.permission.models.PermissionTile import com.naviapp.utils.isValidIndex class PermissionV2Adapter : RecyclerView.Adapter() { diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/EmploymentVerificationV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/EmploymentVerificationV2Fragment.kt index e34aa6ab09..27380769dd 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/EmploymentVerificationV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/EmploymentVerificationV2Fragment.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.useridentificationv2.fragments /* @@ -57,9 +64,8 @@ import com.naviapp.utils.Constants.IS_COMING_FROM_WORK_DETAILS import com.naviapp.utils.Constants.OFFER import com.naviapp.utils.Constants.OFFER_UPGRADE - -class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, - FooterViewV2.FooterInteractionListener , BackListener{ +class EmploymentVerificationV2Fragment : + BaseFragment(), View.OnClickListener, FooterViewV2.FooterInteractionListener, BackListener { private lateinit var binding: EmploymentVerificationV2LayoutBinding private var sharedSearchViewModel: SearchViewModel? = null @@ -84,10 +90,7 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, savedInstanceState: Bundle? ): View { binding = EmploymentVerificationV2LayoutBinding.inflate(inflater, container, false) - initError( - viewModel, - actionErrorV2Enabled = true - ) + initError(viewModel, actionErrorV2Enabled = true) initWarning() initObservers() initUi() @@ -97,15 +100,16 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - flowType = when { - arguments?.getBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE) == true -> { - NaviAnalytics.LOAN_OFFER_UPGRADE + flowType = + when { + arguments?.getBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE) == true -> { + NaviAnalytics.LOAN_OFFER_UPGRADE + } + arguments?.getBoolean(IS_COMING_FROM_WORK_DETAILS) == true -> { + NaviAnalytics.WORK_DETAIL + } + else -> EMPTY } - arguments?.getBoolean(IS_COMING_FROM_WORK_DETAILS) == true -> { - NaviAnalytics.WORK_DETAIL - } - else -> EMPTY - } } override fun onAttach(context: Context) { @@ -115,14 +119,7 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, } private fun initWarning() { - initWarning( - viewModel, listOf( - Triple( - primaryWarningAction, null, - ApiErrorTagType.EPFO - ) - ) - ) + initWarning(viewModel, listOf(Triple(primaryWarningAction, null, ApiErrorTagType.EPFO))) } private fun initListeners() { @@ -135,15 +132,19 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, private fun initUi() { showLoader() fetchEPFODetails() - binding.companySelectorContainer.background = getNaviDrawable( - cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), - strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), - strokeColor = ResourcesCompat.getColor(resources, R.color.border_dark_grey_color, null) - ) - binding.generateOtpContainer.background = getNaviDrawable( - backgroundColor = ResourcesCompat.getColor(resources, R.color.red_light_three, null), - cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt() - ) + binding.companySelectorContainer.background = + getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt(), + strokeWidth = resources.getDimension(R.dimen.layout_dp_1).toInt(), + strokeColor = + ResourcesCompat.getColor(resources, R.color.border_dark_grey_color, null) + ) + binding.generateOtpContainer.background = + getNaviDrawable( + backgroundColor = + ResourcesCompat.getColor(resources, R.color.red_light_three, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_8).toInt() + ) } override fun onCreate(savedInstanceState: Bundle?) { @@ -163,31 +164,18 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, naviAnalyticsEventTracker.onEPFONotValid() if (arguments?.getBoolean(IS_COMING_FROM_WORK_DETAILS).orFalse()) { viewModel.employmentVerificationResponse.value?.footer?.nextCta?.url?.let { - fragmentInterchangeListener?.navigateToNextScreen( - it, - Bundle() - ) + fragmentInterchangeListener?.navigateToNextScreen(it, Bundle()) return@observeNonNull } - } else if (arguments?.getBoolean(IS_COMING_FROM_QUESTIONNAIRE_PAGE) - .orFalse() - ) { + } else if (arguments?.getBoolean(IS_COMING_FROM_QUESTIONNAIRE_PAGE).orFalse()) { viewModel.employmentVerificationResponse.value?.footer?.backCta?.url?.let { - fragmentInterchangeListener?.navigateToNextScreen( - it, - Bundle() - ) + fragmentInterchangeListener?.navigateToNextScreen(it, Bundle()) } - } else if (arguments?.getBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE) - .orFalse() - ) { + } else if (arguments?.getBoolean(IS_COMING_FROM_OFFER_UPGRADE_PAGE).orFalse()) { activity?.finish() } else { viewModel.employmentVerificationResponse.value?.footer?.nextCta?.url?.let { - fragmentInterchangeListener?.navigateToNextScreen( - it, - Bundle() - ) + fragmentInterchangeListener?.navigateToNextScreen(it, Bundle()) } } return@observeNonNull @@ -227,23 +215,18 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, viewModel.sendOtp.observeNullable(this) { handleDisbursementOtpResponse(it) } otpSharedViewModel?.otpVerified?.observeNullable(viewLifecycleOwner) { - it?.let { - handleOtpVerified( - it - ) - } + it?.let { handleOtpVerified(it) } } } - private fun handleDisbursementOtpResponse(sendDisbursementOtpResponse: SendDisbursementOtpResponse?) { + private fun handleDisbursementOtpResponse( + sendDisbursementOtpResponse: SendDisbursementOtpResponse? + ) { hideLoader() sendDisbursementOtpResponse?.let { val bundle = Bundle() it.retryTimeInSecs?.let { retryTimeInSecs -> - bundle.putInt( - OtpBottomSheet.KEY_EXPIRY_TIME, - retryTimeInSecs - ) + bundle.putInt(OtpBottomSheet.KEY_EXPIRY_TIME, retryTimeInSecs) } bundle.putString(OtpBottomSheet.KEY_OTP_TOKEN, it.otpToken) bundle.putInt(OtpBottomSheet.KEY_OTP_SIZE, it.otpSize.orValue(OTP_LENGTH_6)) @@ -268,7 +251,8 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, binding.epfoTitleContainer.isVisible = false binding.generateOtpContainer.isVisible = false context?.customToast( - customView = getFilledToastView(resources.getString(R.string.verification_successful)), + customView = + getFilledToastView(resources.getString(R.string.verification_successful)), offsetY = resources.getDimension(R.dimen.layout_dp_120).toInt(), gravity = Gravity.BOTTOM or Gravity.FILL_HORIZONTAL ) @@ -278,17 +262,15 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, } private fun getFilledToastView(text: String?): View { - return CustomToastBinding.inflate( - layoutInflater, null, false - ).apply { - toastIv.setImageResource(R.drawable.ic_green_tick_small) - toastLayoutRoot.setBackgroundResource(R.drawable.bg_light_green_rounded_12) - toastTv.text = text - context?.let { - toastTv.setTextColor(ContextCompat.getColor(it, R.color.green)) + return CustomToastBinding.inflate(layoutInflater, null, false) + .apply { + toastIv.setImageResource(R.drawable.ic_green_tick_small) + toastLayoutRoot.setBackgroundResource(R.drawable.bg_light_green_rounded_12) + toastTv.text = text + context?.let { toastTv.setTextColor(ContextCompat.getColor(it, R.color.green)) } + TextViewCompat.setTextAppearance(toastTv, R.style.NaviSansBoldExtraSmall) } - TextViewCompat.setTextAppearance(toastTv, R.style.NaviSansBoldExtraSmall) - }.root + .root } private fun fetchEPFODetails() { @@ -297,21 +279,29 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, } private fun openBankSelector() { - if (viewModel.employmentVerificationResponse.value?.content?.epfoDetails?.isOtpVerified.orFalse() || otpSharedViewModel?.otpVerified?.value.orFalse()) { + if ( + viewModel.employmentVerificationResponse.value + ?.content + ?.epfoDetails + ?.isOtpVerified + .orFalse() || otpSharedViewModel?.otpVerified?.value.orFalse() + ) { activity?.toast( - getString(R.string.company_can_not_be_change), offsetY = 700, + getString(R.string.company_can_not_be_change), + offsetY = 700, length = Toast.LENGTH_SHORT ) } else { if (!isAdded || activity?.isFinishing.orTrue()) return val bundle = Bundle() bundle.putString(FLOW_TYPE, flowType) - val searchFragment = SearchFragment.newInstance( - resources.getString(R.string.select_company), - SearchFragment.SearchType.COMPANY_INDUSTRY, - null, - bundle - ) + val searchFragment = + SearchFragment.newInstance( + resources.getString(R.string.select_company), + SearchFragment.SearchType.COMPANY_INDUSTRY, + null, + bundle + ) if (!childFragmentManager.isDestroyed && !childFragmentManager.isStateSaved) searchFragment.show(childFragmentManager, SearchFragment.TAG) naviAnalyticsEventTracker.onCompanyTap(flowType) @@ -335,11 +325,12 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, naviAnalyticsEventTracker.onOtpInfoTap() naviAnalyticsEventTracker.onBottomSheetOpen(flowType) viewModel.employmentVerificationResponse.value?.content?.epfoDetails?.epfoInfo?.let { - val bottomSheet = InfoBottomSheetV2.getInstance( - header = it.title, - subHeader = it.message, - ctaData = CtaData(it.actions?.first()?.title) - ) + val bottomSheet = + InfoBottomSheetV2.getInstance( + header = it.title, + subHeader = it.message, + ctaData = CtaData(it.actions?.first()?.title) + ) safelyShowBottomSheet(bottomSheet, InfoBottomSheetV2.TAG) bottomSheet.ctaClickListener.observeNonNull(viewLifecycleOwner) { naviAnalyticsEventTracker.onBottomSheetCtaClicked(flowType) @@ -377,9 +368,7 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, naviAnalyticsEventTracker.onBackButtonPressed(flowType) backCta?.url?.let { naviAnalyticsEventTracker.onEPFOBackButtonTap() - fragmentInterchangeListener?.navigateToNextScreen( - it, Bundle() - ) + fragmentInterchangeListener?.navigateToNextScreen(it, Bundle()) } } @@ -395,16 +384,16 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, } else { naviAnalyticsEventTracker.onSkipButtonClick(flowType) } - if (arguments?.getString(EPFO_PAGE_TYPE) == OFFER || arguments?.getString(EPFO_PAGE_TYPE) == OFFER_UPGRADE) { + if ( + arguments?.getString(EPFO_PAGE_TYPE) == OFFER || + arguments?.getString(EPFO_PAGE_TYPE) == OFFER_UPGRADE + ) { bundle.apply { putStringArrayList(IntentConstants.OFFER_IMPROVEMENT_CHANNEL_TYPE, channelList) } NaviDeepLinkNavigator.navigate(activity, nextCta, bundle = bundle) } else { - fragmentInterchangeListener?.navigateToNextScreen( - it, - bundle - ) + fragmentInterchangeListener?.navigateToNextScreen(it, bundle) } } } @@ -433,6 +422,4 @@ class EmploymentVerificationV2Fragment : BaseFragment(), View.OnClickListener, return fragment } } - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/InformationBottomSheet.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/InformationBottomSheet.kt index 311e8d85a0..97280ad380 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/InformationBottomSheet.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/InformationBottomSheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.personalloanrevamp.useridentificationv2.fragments import android.os.Bundle @@ -50,26 +57,25 @@ class InformationBottomSheet : BaseBottomSheet() { companion object { private const val KEY_DATA = "KEY_DATA" const val TAG = "INFORMATION_BOTTOM_SHEET" - val defaultData = InfoBottomSheetConfig( - iconCode = "ICON_ALERT_BLACK", - title = "Know more", - styledDescription = StyledTextWithIconCode( - text = "Navi takes Data Security and Privacy seriously. Our Information " + - "Security Program is based on a holistic approach involving People, " + - "Process and Technology. \n\nWe follow industry best practices to " + - "scale, protect and secure data from the ever-growing threats." - ), - cta = CtaData(title = "Okay, got it") - - ) + val defaultData = + InfoBottomSheetConfig( + iconCode = "ICON_ALERT_BLACK", + title = "Know more", + styledDescription = + StyledTextWithIconCode( + text = + "Navi takes Data Security and Privacy seriously. Our Information " + + "Security Program is based on a holistic approach involving People, " + + "Process and Technology. \n\nWe follow industry best practices to " + + "scale, protect and secure data from the ever-growing threats." + ), + cta = CtaData(title = "Okay, got it") + ) fun getInstance(infoBottomSheetConfig: InfoBottomSheetConfig): InformationBottomSheet { return InformationBottomSheet().apply { - arguments = Bundle().apply { - putParcelable(KEY_DATA, infoBottomSheetConfig) - } + arguments = Bundle().apply { putParcelable(KEY_DATA, infoBottomSheetConfig) } } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/MFIConsentV2Fragment.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/MFIConsentV2Fragment.kt index 04e5a8b810..c579ded709 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/MFIConsentV2Fragment.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/fragments/MFIConsentV2Fragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -34,7 +34,9 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListener { private lateinit var binding: MfiConsentV2FragmentBinding - private val viewModel by lazy { ViewModelProvider(requireActivity()).get(MfiConsentVM::class.java) } + private val viewModel by lazy { + ViewModelProvider(requireActivity()).get(MfiConsentVM::class.java) + } private val naviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.MFIConsent() private var fragmentListener: FragmentInteractionListener? = null private var headerListener: NaviHeaderView.InteractionListener? = null @@ -86,10 +88,11 @@ class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListe private fun moveToNextScreen() { viewModel.mfiConsentResponse.value?.content?.bottomSheetData?.primaryCta?.let { - val bundle = Bundle().apply { - putString(ErrorActivity.IS_SOFT_REJECT, Constants.TRUE) - putString(Constants.WIDGET_ID, Constants.PERSONAL_LOAN) - } + val bundle = + Bundle().apply { + putString(ErrorActivity.IS_SOFT_REJECT, Constants.TRUE) + putString(Constants.WIDGET_ID, Constants.PERSONAL_LOAN) + } NaviDeepLinkNavigator.navigate( activity = activity, ctaData = it, @@ -103,9 +106,7 @@ class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListe binding.strikeTv.setOnClickListener { naviAnalyticsEventTracker.onClickingHyperLink() viewModel.mfiConsentResponse.value?.content?.info?.cta?.url?.let { - fragmentListener?.navigateTo( - it - ) + fragmentListener?.navigateTo(it) } } } @@ -125,7 +126,6 @@ class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListe hideDivider = true ) binding.strikeTv.makeUnderlined() - } override fun onFooterBackPressed(backCta: CtaData?) { @@ -145,7 +145,6 @@ class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListe viewModel.submitMfiAgreeConsent(YES.uppercase()) } - override val screenName: String get() = NaviAnalytics.MFI_CONSENT_SCREEN_V2 @@ -154,4 +153,4 @@ class MFIConsentV2Fragment : BaseFragment(), FooterViewV2.FooterInteractionListe private const val YES = "yes" private const val NO = "no" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/helper/PermissionV2Helper.kt b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/helper/PermissionV2Helper.kt index df824b5d6d..6eebdc895f 100644 --- a/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/helper/PermissionV2Helper.kt +++ b/app/src/main/java/com/naviapp/personalloanrevamp/useridentificationv2/helper/PermissionV2Helper.kt @@ -16,13 +16,13 @@ import android.provider.Settings import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import com.navi.common.managers.PermissionsManager +import com.navi.common.model.permission.PermissionTile import com.navi.common.utils.log import com.naviapp.BuildConfig import com.naviapp.R import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.app.NaviApplication import com.naviapp.permission.models.PermissionDeniedBinder -import com.naviapp.permission.models.PermissionTile import com.naviapp.utils.Constants import com.naviapp.utils.EMPTY diff --git a/app/src/main/java/com/naviapp/pushnotification/firebase/NaviFirebaseMessagingService.kt b/app/src/main/java/com/naviapp/pushnotification/firebase/NaviFirebaseMessagingService.kt index 05da50df09..3a3033b14c 100644 --- a/app/src/main/java/com/naviapp/pushnotification/firebase/NaviFirebaseMessagingService.kt +++ b/app/src/main/java/com/naviapp/pushnotification/firebase/NaviFirebaseMessagingService.kt @@ -21,6 +21,7 @@ import com.navi.analytics.moengage.MoengageUtil import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.sharedpref.PreferenceManager import com.navi.chat.ui.activities.NaviChatActivity +import com.navi.chat.utils.CHAT_PN_RECEIVED import com.navi.common.model.ModuleName import com.navi.common.model.PushNotificationData import com.navi.common.repositories.FcmCallbackRepository @@ -134,11 +135,11 @@ class NaviFirebaseMessagingService : FirebaseMessagingService() { intent.putExtra(key, value) } } - if ( - intent.getStringExtra(Constants.DEEPLINK) == CHAT_ACTIVITY && - NaviChatActivity.isChatActivityVisible - ) { - return + if (intent.getStringExtra(Constants.DEEPLINK) == CHAT_ACTIVITY) { + NaviTrackEvent.trackEventOnClickStream(CHAT_PN_RECEIVED) + if (NaviChatActivity.isChatActivityVisible) { + return + } } val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { diff --git a/app/src/main/java/com/naviapp/registration/LoginFragment.kt b/app/src/main/java/com/naviapp/registration/LoginFragment.kt index c58d0eb889..483d8add5b 100644 --- a/app/src/main/java/com/naviapp/registration/LoginFragment.kt +++ b/app/src/main/java/com/naviapp/registration/LoginFragment.kt @@ -43,6 +43,7 @@ import com.naviapp.registration.viewmodel.RegistrationSharedVM import com.naviapp.registration.viewmodel.RegistrationVM import com.naviapp.utils.* import com.naviapp.utils.Constants +import com.naviapp.utils.Constants.CALL_ENABLED import com.naviapp.utils.Constants.LEGAL_DOC_TYPE_PRIVACY_POLICY import com.naviapp.utils.Constants.LEGAL_DOC_TYPE_TNC import com.naviapp.utils.Constants.VALID_PHONE_NUMBER_LENGTH @@ -75,13 +76,16 @@ class LoginFragment : BaseFragment(), View.OnClickListener { private fun initObservers() { registrationVM.otpTokenAndPhone.observeNonNull(this) { otpTokenAndPhone -> - BaseUtils.savePhoneNumber(otpTokenAndPhone.second) + BaseUtils.savePhoneNumber(otpTokenAndPhone.phoneNumber.orEmpty()) hideLoader() analyticsEventTracker.onOTPDeliverySuccess(source) val bundle = arguments ?: Bundle() listener?.navigateTo( OTP_SCREEN, - bundle.apply { putString(OTP_TOKEN, otpTokenAndPhone.first) } + bundle.apply { + putString(OTP_TOKEN, otpTokenAndPhone.otpToken.orEmpty()) + putBoolean(CALL_ENABLED, otpTokenAndPhone.callEnabled.orFalse()) + } ) } } @@ -245,7 +249,7 @@ class LoginFragment : BaseFragment(), View.OnClickListener { private fun navigateToOtpScreenOrEnableOtpButton() { if ( binding.phoneEdit.text.toString().length == VALID_PHONE_NUMBER_LENGTH && - (isCheckBoxNeedToShow.not() || binding.conditionsCb.isChecked) + (isCheckBoxNeedToShow.not() || binding.conditionsCb.isChecked) ) { binding.getOtpBtn.setViewBg(bgColor = R.color.active_button_color) } else { diff --git a/app/src/main/java/com/naviapp/registration/OtpFragment.kt b/app/src/main/java/com/naviapp/registration/OtpFragment.kt index 63711f2158..8fc99e5dae 100644 --- a/app/src/main/java/com/naviapp/registration/OtpFragment.kt +++ b/app/src/main/java/com/naviapp/registration/OtpFragment.kt @@ -60,6 +60,7 @@ class OtpFragment : BaseFragment(), View.OnClickListener { private var apiCallLastTime: Long = 0 private var grootReferenceId: String? = null private var channel: String? = null + private var isCallOptionEnabled = false override fun onAttach(context: Context) { super.onAttach(context) @@ -136,7 +137,8 @@ class OtpFragment : BaseFragment(), View.OnClickListener { } registrationVM.otpTokenAndPhone.observeNonNull(this) { otpTokenAndPhone -> - latestOtpToken = otpTokenAndPhone.first + latestOtpToken = otpTokenAndPhone.otpToken.orEmpty() + isCallOptionEnabled = otpTokenAndPhone.callEnabled.orFalse() } } @@ -150,6 +152,7 @@ class OtpFragment : BaseFragment(), View.OnClickListener { } private fun initUi() { + isCallOptionEnabled = arguments?.getBoolean(Constants.CALL_ENABLED).orFalse() arguments?.getString(OTP_TOKEN)?.let { latestOtpToken = it } binding.verifyOtpBtn.setProperties( getString(R.string.verify), @@ -205,8 +208,10 @@ class OtpFragment : BaseFragment(), View.OnClickListener { if (isAdded) { binding.countdownTimerTv.visibility = View.INVISIBLE binding.resendOtpTv.visibility = View.VISIBLE - binding.otpOncallTv.visibility = View.VISIBLE binding.noCallDisclaimer.headerLayout.isVisible = false + if (isCallOptionEnabled) { + binding.otpOncallTv.visibility = View.VISIBLE + } } } } @@ -353,7 +358,7 @@ class OtpFragment : BaseFragment(), View.OnClickListener { private fun hideResendOtpOnCallUiState() { if (binding.resendOtpTv.visibility != View.INVISIBLE) binding.resendOtpTv.visibility = View.INVISIBLE - if (binding.otpOncallTv.visibility != View.INVISIBLE) + if (binding.otpOncallTv.visibility != View.INVISIBLE && isCallOptionEnabled) binding.otpOncallTv.visibility = View.INVISIBLE binding.countdownTimerTv.visibility = View.VISIBLE diff --git a/app/src/main/java/com/naviapp/registration/SplashActivity.kt b/app/src/main/java/com/naviapp/registration/SplashActivity.kt index 115251ac57..af8331898c 100644 --- a/app/src/main/java/com/naviapp/registration/SplashActivity.kt +++ b/app/src/main/java/com/naviapp/registration/SplashActivity.kt @@ -43,13 +43,20 @@ import com.navi.base.sharedpref.PreferenceManager import com.navi.base.utils.BaseUtils import com.navi.base.utils.orZero import com.navi.chat.ui.activities.NaviChatActivity +import com.navi.chat.utils.CHAT_PN_OPENED +import com.navi.chat.utils.CHAT_SCREEN +import com.navi.chat.utils.HOME_SCREEN +import com.navi.chat.utils.SCREEN_NAME import com.navi.common.extensions.isNotNull import com.navi.common.managers.NaviLocationManager.Companion.LOCATION_UPDATE_DURATION import com.navi.common.model.ModuleNameV2 import com.navi.common.model.PushNotificationData import com.navi.common.ui.activity.BaseActivity -import com.navi.common.utils.* import com.navi.common.utils.Constants.LOGIN_SOURCE +import com.navi.common.utils.getSessionId +import com.navi.common.utils.observeNullable +import com.navi.common.utils.orFalse +import com.navi.common.utils.orTrue import com.naviapp.BuildConfig import com.naviapp.R import com.naviapp.analytics.deeplink.DeeplinkManager @@ -75,7 +82,6 @@ import com.naviapp.registration.viewmodel.ConfigVM import com.naviapp.registration.viewmodel.RegistrationVM import com.naviapp.services.KillAppInBackgroundService import com.naviapp.utils.* -import com.naviapp.utils.Constants import com.naviapp.utils.Constants.DEEPLINK import com.naviapp.utils.Constants.EXPIRY_TIME_IN_MIN import com.naviapp.utils.Constants.FCM_CLICKED @@ -397,8 +403,16 @@ class SplashActivity : BaseActivity(), DeepLinkListener { ) ) param.add(LineItem(NaviDeepLinkNavigator.IS_FROM_NOTIFICATION, "true")) + NaviTrackEvent.trackEventOnClickStream( + CHAT_PN_OPENED, + mapOf(SCREEN_NAME to CHAT_SCREEN) + ) } else { deeplink = HOME + NaviTrackEvent.trackEventOnClickStream( + CHAT_PN_OPENED, + mapOf(SCREEN_NAME to HOME_SCREEN) + ) } } val ctaData = CtaData(url = deeplink) diff --git a/app/src/main/java/com/naviapp/registration/viewmodel/RegistrationVM.kt b/app/src/main/java/com/naviapp/registration/viewmodel/RegistrationVM.kt index 21194377eb..79f44cd283 100644 --- a/app/src/main/java/com/naviapp/registration/viewmodel/RegistrationVM.kt +++ b/app/src/main/java/com/naviapp/registration/viewmodel/RegistrationVM.kt @@ -31,8 +31,8 @@ import timber.log.Timber class RegistrationVM(private val registerRepository: RegisterRepository = RegisterRepository()) : BaseVM() { - private val _otpTokenAndPhone = MutableLiveData>() - val otpTokenAndPhone: LiveData> + private val _otpTokenAndPhone = MutableLiveData() + val otpTokenAndPhone: LiveData get() = _otpTokenAndPhone private val _otpTokenFailure = MutableLiveData() @@ -127,7 +127,10 @@ class RegistrationVM(private val registerRepository: RegisterRepository = Regist setError(response.errors) return@launch } - response.data?.otpToken?.let { _otpTokenAndPhone.value = Pair(it, phoneNumber) } + response.data?.otpToken?.let { + response.data?.phoneNumber = phoneNumber + _otpTokenAndPhone.value = response.data + } } response.error?.statusCode == API_TOO_MANY_REQUESTS -> { setError(response.errors) diff --git a/app/src/main/java/com/naviapp/rewards/interfaces/ActionButtonClickListener.kt b/app/src/main/java/com/naviapp/rewards/interfaces/ActionButtonClickListener.kt index e49e473f70..b019b07d1c 100644 --- a/app/src/main/java/com/naviapp/rewards/interfaces/ActionButtonClickListener.kt +++ b/app/src/main/java/com/naviapp/rewards/interfaces/ActionButtonClickListener.kt @@ -1,7 +1,14 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.rewards.interfaces import com.navi.base.model.NaviWidgetClickWithActionData interface ActionButtonClickListener { fun onCtaClick(naviWidgetClickWithActionData: NaviWidgetClickWithActionData?) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardDelightActivity.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardDelightActivity.kt index 296f229b17..15c6277b7d 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardDelightActivity.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardDelightActivity.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -39,23 +37,17 @@ import com.naviapp.personalloan.getloan.viewmodels.LoanDisbursementVM import com.naviapp.rewards.interfaces.ActionButtonClickListener import com.naviapp.utils.Constants - class RewardDelightActivity : BaseActivity(), ActionButtonClickListener { private lateinit var binding: ActivityRewardDelightBinding private var rewardsWidgetData: RewardWidgetData? = null private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() - private val viewModel by lazy { - ViewModelProvider(this).get(LoanDisbursementVM::class.java) - } + private val viewModel by lazy { ViewModelProvider(this).get(LoanDisbursementVM::class.java) } private val analyticsEventTracker = NaviAnalytics.naviAnalytics.FullPageProcessingDetail() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView( - this, - R.layout.activity_reward_delight - ) + binding = DataBindingUtil.setContentView(this, R.layout.activity_reward_delight) setContentView(binding.root) readArguments() initUI() @@ -86,41 +78,45 @@ class RewardDelightActivity : BaseActivity(), ActionButtonClickListener { screenName = it, bundle = bundle ) - } ?: kotlin.run { - viewModel.abSettings.value?.result?.let { result -> - navigateNextScreen( - screenName = if (result) { - ScreenNavigator.CROSS_SELL_SCREEN - } else { - ScreenNavigator.LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN - }, - bundle = Bundle() - ) - } ?: kotlin.run { - navigateNextScreen( - screenName = ScreenNavigator.LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN, - bundle = Bundle() - ) - } } + ?: kotlin.run { + viewModel.abSettings.value?.result?.let { result -> + navigateNextScreen( + screenName = + if (result) { + ScreenNavigator.CROSS_SELL_SCREEN + } else { + ScreenNavigator.LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN + }, + bundle = Bundle() + ) + } + ?: kotlin.run { + navigateNextScreen( + screenName = ScreenNavigator.LOAN_DISBURSEMENT_PRODUCT_PLACEMENT_SCREEN, + bundle = Bundle() + ) + } + } } private fun navigateNextScreen(screenName: String, bundle: Bundle) { - Handler(Looper.getMainLooper()).postDelayed( - { - if (isDead()) return@postDelayed - bundle.putParcelable( - Constants.PREVIOUS_SCREEN, - PreviousScreenNameRequest(Constants.DISBURSED) - ) - ScreenNavigator.instance.startActivityWithNoActivityStack( - this, - screenName, - bundle - ) - }, - NEXT_SCREEN_TRANSITION_DELAY - ) + Handler(Looper.getMainLooper()) + .postDelayed( + { + if (isDead()) return@postDelayed + bundle.putParcelable( + Constants.PREVIOUS_SCREEN, + PreviousScreenNameRequest(Constants.DISBURSED) + ) + ScreenNavigator.instance.startActivityWithNoActivityStack( + this, + screenName, + bundle + ) + }, + NEXT_SCREEN_TRANSITION_DELAY + ) } private fun initUI() { @@ -141,9 +137,7 @@ class RewardDelightActivity : BaseActivity(), ActionButtonClickListener { tvRewardPrice.showWhenDataIsAvailable(showText = rewardsWidgetData?.rewardsInfo?.value) tvRewardType.showWhenDataIsAvailable(showText = rewardsWidgetData?.rewardsInfo?.label) ivRewardIcon.showWhenDataIsAvailable( - imageDetail = ImageDetail( - url = rewardsWidgetData?.rewardsInfo?.largeIconUrl - ) + imageDetail = ImageDetail(url = rewardsWidgetData?.rewardsInfo?.largeIconUrl) ) if (rewardsWidgetData?.rewardsInfo?.showCornerImg == true) { ivCornerImg.setImageResource( @@ -163,38 +157,44 @@ class RewardDelightActivity : BaseActivity(), ActionButtonClickListener { } ) } - ivRewardLottie.showWhenDataIsAvailable(lottieName = rewardsWidgetData?.rewardsInfo?.lottieFileName) + ivRewardLottie.showWhenDataIsAvailable( + lottieName = rewardsWidgetData?.rewardsInfo?.lottieFileName + ) rudbsvDetails.setProperties( rewardsUnlockDetails = rewardsWidgetData?.bottomSheetData?.rewardUnlockedInfo, actionButtonClickListener = this@RewardDelightActivity - ) - widgetNaviAnalyticsEventTracker.onWidgetClickEvent(ActionData(metaData = rewardsWidgetData?.bottomSheetData?.metaData)) + widgetNaviAnalyticsEventTracker.onWidgetClickEvent( + ActionData(metaData = rewardsWidgetData?.bottomSheetData?.metaData) + ) } } private fun animateScreen() { binding.root.post { - val animator = ObjectAnimator.ofFloat( - binding.clAnimation, - TRANSLATION_Y, - this.resources.displayMetrics.heightPixels.toFloat(), - 0f - ) + val animator = + ObjectAnimator.ofFloat( + binding.clAnimation, + TRANSLATION_Y, + this.resources.displayMetrics.heightPixels.toFloat(), + 0f + ) animator.duration = SCREEN_ANIMATION_DELAY animator.interpolator = EasingInterpolator(Ease.EASE_IN_OUT_EXPO) - animator.addListener(object : Animator.AnimatorListener { - override fun onAnimationStart(p0: Animator?) {} + animator.addListener( + object : Animator.AnimatorListener { + override fun onAnimationStart(p0: Animator?) {} - override fun onAnimationEnd(p0: Animator?) { - binding.lavConfetti.playAnimation() - animateComponents() + override fun onAnimationEnd(p0: Animator?) { + binding.lavConfetti.playAnimation() + animateComponents() + } + + override fun onAnimationCancel(p0: Animator?) {} + + override fun onAnimationRepeat(p0: Animator?) {} } - - override fun onAnimationCancel(p0: Animator?) {} - - override fun onAnimationRepeat(p0: Animator?) {} - }) + ) animator.start() } } @@ -232,9 +232,9 @@ class RewardDelightActivity : BaseActivity(), ActionButtonClickListener { get() = ModuleNameV2.COMMON override fun onCtaClick(naviWidgetClickWithActionData: NaviWidgetClickWithActionData?) { - widgetNaviAnalyticsEventTracker.onWidgetClickEvent(naviWidgetClickWithActionData?.actionData) - naviWidgetClickWithActionData?.actionData?.let { - navigateToNextScreen() - } + widgetNaviAnalyticsEventTracker.onWidgetClickEvent( + naviWidgetClickWithActionData?.actionData + ) + naviWidgetClickWithActionData?.actionData?.let { navigateToNextScreen() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardInfoActivity.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardInfoActivity.kt index 1bbdde27d9..6c640b63df 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardInfoActivity.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardInfoActivity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.rewards.ui /* * @@ -34,38 +41,28 @@ import com.naviapp.utils.Constants.PRODUCT_TYPE import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class RewardInfoActivity : BaseActivity(), WidgetCallback{ +class RewardInfoActivity : BaseActivity(), WidgetCallback { private lateinit var binding: ActivityRewardInfoLayoutBinding private val eventTracker = NaviAnalytics.naviAnalytics.RewardsInfo() private var productType: String? = null private var apiContext: String? = null private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() private var linearLayoutManager: LinearLayoutManager? = null - private val naviAdapter = NaviAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) - private val naviFooterAdapter = NaviAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) + private val naviAdapter = NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) + private val naviFooterAdapter = + NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) private val viewModel by lazy { ViewModelProvider(this).get(RewardInfoVM::class.java) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView( - this, - R.layout.activity_reward_info_layout - ) + binding = DataBindingUtil.setContentView(this, R.layout.activity_reward_info_layout) super.setContentView(binding.root) readArguments() initUI() initObserver() initError( viewModel = viewModel, - dialogDismissClicked = { - fetchRewardInfo() - }, + dialogDismissClicked = { fetchRewardInfo() }, showFullScreenError = true ) fetchRewardInfo() @@ -92,8 +89,6 @@ class RewardInfoActivity : BaseActivity(), WidgetCallback{ eventTracker.onBackButtonClick(productType) finish() } - - } } @@ -108,11 +103,8 @@ class RewardInfoActivity : BaseActivity(), WidgetCallback{ if (contentWidget.isEmpty()) { isVisible = false } else { - linearLayoutManager = LinearLayoutManager( - context, - LinearLayoutManager.VERTICAL, - false - ) + linearLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) layoutManager = linearLayoutManager naviAdapter.list = contentWidget adapter = naviAdapter @@ -139,11 +131,8 @@ class RewardInfoActivity : BaseActivity(), WidgetCallback{ private fun processFooter(response: RewardInfoResponse?) { response?.footerWidget?.let { it -> binding.rvFooter.apply { - linearLayoutManager = LinearLayoutManager( - context, - LinearLayoutManager.VERTICAL, - false - ) + linearLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) layoutManager = linearLayoutManager naviFooterAdapter.list = it adapter = naviFooterAdapter @@ -182,7 +171,4 @@ class RewardInfoActivity : BaseActivity(), WidgetCallback{ } } } - - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardSummaryActivity.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardSummaryActivity.kt index bbf3a097ef..0c19d94a5d 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardSummaryActivity.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardSummaryActivity.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.rewards.ui /* * @@ -43,27 +50,19 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism private val eventTracker = NaviAnalytics.naviAnalytics.RewardsSummary() private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() private var linearLayoutManager: LinearLayoutManager? = null - private val naviAdapter = NaviAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) + private val naviAdapter = NaviAdapter(widgetCallback = this, factory = ViewHolderFactoryImpl()) private val viewModel by lazy { ViewModelProvider(this).get(RewardSummaryVM::class.java) } private lateinit var rewardWidgetAnimationView: View override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = DataBindingUtil.setContentView( - this, - R.layout.activity_reward_summary_layout - ) + binding = DataBindingUtil.setContentView(this, R.layout.activity_reward_summary_layout) super.setContentView(binding.root) initUI() initObserver() initError( viewModel = viewModel, - dialogDismissClicked = { - fetchRewardSummary() - }, + dialogDismissClicked = { fetchRewardSummary() }, showFullScreenError = true ) fetchRewardSummary() @@ -81,9 +80,7 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism CustomerSupportFragment.newInstance(screenName, "") .show(supportFragmentManager, CustomerSupportFragment.TAG) } - backBtn.setOnClickListener { - finish() - } + backBtn.setOnClickListener { finish() } } } @@ -93,10 +90,7 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism widgetNaviAnalyticsEventTracker.onWidgetClickEvent(naviClickAction.actionData) NaviTrackEvent.setStartTs(screenName) naviClickAction.actionData?.let { - NaviDeepLinkNavigator.navigate( - this, - it.toCtaData() - ) + NaviDeepLinkNavigator.navigate(this, it.toCtaData()) } } is RewardWidgetClickAction -> { @@ -107,20 +101,27 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism if (::rewardWidgetAnimationView.isInitialized) { moveAnimation( view = rewardWidgetAnimationView, - width = this.resources.displayMetrics.widthPixels / 2f - rewardWidgetPositionArray[0] - + width = + this.resources.displayMetrics.widthPixels / 2f - + rewardWidgetPositionArray[0] - (rewardWidgetAnimationView.width / 2f), - height = this.resources.displayMetrics.heightPixels / 2f - rewardWidgetPositionArray[1] - + height = + this.resources.displayMetrics.heightPixels / 2f - + rewardWidgetPositionArray[1] - rewardWidgetAnimationView.height, duration = ANIMATION_TIME ) } - val rewardsDetailFragment = RewardsDetailFragment.getInstance( - rewardsWidgetData = naviClickAction.rewardWidgetData, - rewardsOverlayDismiss = this@RewardSummaryActivity - ) + val rewardsDetailFragment = + RewardsDetailFragment.getInstance( + rewardsWidgetData = naviClickAction.rewardWidgetData, + rewardsOverlayDismiss = this@RewardSummaryActivity + ) safelyOpenFragment(rewardsDetailFragment, RewardsDetailFragment.TAG) - widgetNaviAnalyticsEventTracker.onWidgetClickEvent(ActionData(metaData = naviClickAction.rewardWidgetData.metaData)) + widgetNaviAnalyticsEventTracker.onWidgetClickEvent( + ActionData(metaData = naviClickAction.rewardWidgetData.metaData) + ) } } } @@ -135,11 +136,8 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism if (contentWidget.isEmpty()) { isVisible = false } else { - linearLayoutManager = LinearLayoutManager( - context, - LinearLayoutManager.VERTICAL, - false - ) + linearLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) layoutManager = linearLayoutManager naviAdapter.list = contentWidget adapter = naviAdapter @@ -196,4 +194,4 @@ class RewardSummaryActivity : BaseActivity(), WidgetCallback, RewardsOverlayDism private const val ANIMATION_TIME = 250L fun getInstance() = RewardSummaryActivity() } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardsDetailFragment.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardsDetailFragment.kt index 2699c427a1..5177305fb8 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardsDetailFragment.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardsDetailFragment.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -33,13 +31,13 @@ import com.naviapp.analytics.utils.NaviAnalytics import com.naviapp.analytics.utils.NaviAnalytics.Companion.REWARDS_DETAILS_SCREEN import com.naviapp.common.navigator.NaviDeepLinkNavigator import com.naviapp.databinding.LayoutRewardsDetailsBinding +import com.naviapp.rewards.interfaces.ActionButtonClickListener import com.naviapp.rewards.interfaces.RewardsOverlayDismiss import com.naviapp.utils.Constants.WEB_URL -import com.naviapp.rewards.interfaces.ActionButtonClickListener -class RewardsDetailFragment : BaseDialogFragment( - layoutId = R.layout.layout_rewards_details -), ActionButtonClickListener { +class RewardsDetailFragment : + BaseDialogFragment(layoutId = R.layout.layout_rewards_details), + ActionButtonClickListener { private var rewardsWidgetData: RewardWidgetData? = null private val widgetNaviAnalyticsEventTracker = NaviAnalytics.naviAnalytics.Widget() @@ -53,12 +51,13 @@ class RewardsDetailFragment : BaseDialogFragment( } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = object : Dialog(requireContext(), theme) { - override fun onBackPressed() { - super.onBackPressed() - rewardsOverlayDismiss?.onRewardsOverlayDismiss() + val dialog = + object : Dialog(requireContext(), theme) { + override fun onBackPressed() { + super.onBackPressed() + rewardsOverlayDismiss?.onRewardsOverlayDismiss() + } } - } return dialog } @@ -91,9 +90,8 @@ class RewardsDetailFragment : BaseDialogFragment( ivLockIcon.visibility = VISIBLE clUnLock.visibility = GONE ivLockIcon.showWhenDataIsAvailable( - imageDetail = ImageDetail( - url = rewardsWidgetData?.rewardsInfo?.largeIconUrl - ) + imageDetail = + ImageDetail(url = rewardsWidgetData?.rewardsInfo?.largeIconUrl) ) } } @@ -114,12 +112,15 @@ class RewardsDetailFragment : BaseDialogFragment( ) ivLockIcon.visibility = GONE clUnLock.visibility = VISIBLE - tvRewardPrice.showWhenDataIsAvailable(showText = rewardsWidgetData?.rewardsInfo?.value) - tvRewardType.showWhenDataIsAvailable(showText = rewardsWidgetData?.rewardsInfo?.label) + tvRewardPrice.showWhenDataIsAvailable( + showText = rewardsWidgetData?.rewardsInfo?.value + ) + tvRewardType.showWhenDataIsAvailable( + showText = rewardsWidgetData?.rewardsInfo?.label + ) ivRewardIcon.showWhenDataIsAvailable( - imageDetail = ImageDetail( - url = rewardsWidgetData?.rewardsInfo?.largeIconUrl - ) + imageDetail = + ImageDetail(url = rewardsWidgetData?.rewardsInfo?.largeIconUrl) ) if (rewardsWidgetData?.rewardsInfo?.showCornerImg == true) { ivCornerImg.setImageResource( @@ -139,7 +140,9 @@ class RewardsDetailFragment : BaseDialogFragment( } ) } - ivRewardLottie.showWhenDataIsAvailable(lottieName = rewardsWidgetData?.rewardsInfo?.lottieFileName) + ivRewardLottie.showWhenDataIsAvailable( + lottieName = rewardsWidgetData?.rewardsInfo?.lottieFileName + ) } } } @@ -149,9 +152,7 @@ class RewardsDetailFragment : BaseDialogFragment( when (rewardsWidgetData?.bottomSheetData?.type) { RewardBottomSheetType.LOCKED.name -> { val rewardsLockDetailsBottomSheetView = - RewardsLockDetailsBottomSheetView( - requireContext() - ) + RewardsLockDetailsBottomSheetView(requireContext()) rewardsLockDetailsBottomSheetView.setProperties( rewardsLockDetails = rewardsWidgetData?.bottomSheetData?.rewardLockedInfo, actionButtonClickListener = this @@ -162,13 +163,16 @@ class RewardsDetailFragment : BaseDialogFragment( val rewardsPLUnlockDetailsBottomSheetView = RewardsPLUnlockDetailsBottomSheetView(requireContext()) rewardsPLUnlockDetailsBottomSheetView.setProperties( - plRewardUnlockDetails = rewardsWidgetData?.bottomSheetData?.plRewardUnlockedInfo, + plRewardUnlockDetails = + rewardsWidgetData?.bottomSheetData?.plRewardUnlockedInfo, actionButtonClickListener = this ) binding.flBottomView.addView(rewardsPLUnlockDetailsBottomSheetView) } } - widgetNaviAnalyticsEventTracker.onWidgetClickEvent(ActionData(metaData = rewardsWidgetData?.bottomSheetData?.metaData)) + widgetNaviAnalyticsEventTracker.onWidgetClickEvent( + ActionData(metaData = rewardsWidgetData?.bottomSheetData?.metaData) + ) } override fun dismiss() { @@ -185,16 +189,19 @@ class RewardsDetailFragment : BaseDialogFragment( fun getInstance( rewardsWidgetData: RewardWidgetData, rewardsOverlayDismiss: RewardsOverlayDismiss? = null - ) = RewardsDetailFragment().apply { - this.rewardsOverlayDismiss = rewardsOverlayDismiss - val bundle = Bundle() - bundle.putParcelable(KEY_REWARD_INFO, rewardsWidgetData) - arguments = bundle - } + ) = + RewardsDetailFragment().apply { + this.rewardsOverlayDismiss = rewardsOverlayDismiss + val bundle = Bundle() + bundle.putParcelable(KEY_REWARD_INFO, rewardsWidgetData) + arguments = bundle + } } override fun onCtaClick(naviWidgetClickWithActionData: NaviWidgetClickWithActionData?) { - widgetNaviAnalyticsEventTracker.onWidgetClickEvent(naviWidgetClickWithActionData?.actionData) + widgetNaviAnalyticsEventTracker.onWidgetClickEvent( + naviWidgetClickWithActionData?.actionData + ) naviWidgetClickWithActionData?.actionData?.let { if (it.url.isNull()) { safelyDismissDialog() @@ -202,11 +209,8 @@ class RewardsDetailFragment : BaseDialogFragment( if (it.url?.equals(WEB_URL) == true) { safelyDismissDialog() } - NaviDeepLinkNavigator.navigate( - activity, - it.toCtaData() - ) + NaviDeepLinkNavigator.navigate(activity, it.toCtaData()) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardsLockDetailsBottomSheetView.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardsLockDetailsBottomSheetView.kt index 3a5cd0a513..935ea7459b 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardsLockDetailsBottomSheetView.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardsLockDetailsBottomSheetView.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -22,36 +20,40 @@ import com.naviapp.R import com.naviapp.databinding.LayoutRewardsLockDetailsBinding import com.naviapp.rewards.interfaces.ActionButtonClickListener -class RewardsLockDetailsBottomSheetView @JvmOverloads constructor( +class RewardsLockDetailsBottomSheetView +@JvmOverloads +constructor( parentContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, ) : ConstraintLayout(parentContext, attrs, defStyleAttr) { - private val binding: LayoutRewardsLockDetailsBinding = DataBindingUtil.inflate( - LayoutInflater.from(context), - R.layout.layout_rewards_lock_details, - this, - true - ) + private val binding: LayoutRewardsLockDetailsBinding = + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_rewards_lock_details, + this, + true + ) private var rewardsLockDetails: RewardLockedDetails? = null - fun setProperties( rewardsLockDetails: RewardLockedDetails?, actionButtonClickListener: ActionButtonClickListener ) { this.rewardsLockDetails = rewardsLockDetails binding.apply { - tvTitle.text = rewardsLockDetails?.title?.text.spannedText( - context = context, - span = rewardsLockDetails?.title?.span - ) - tvDescription.text = rewardsLockDetails?.description?.text.spannedText( - context = context, - span = rewardsLockDetails?.description?.span - ) + tvTitle.text = + rewardsLockDetails + ?.title + ?.text + .spannedText(context = context, span = rewardsLockDetails?.title?.span) + tvDescription.text = + rewardsLockDetails + ?.description + ?.text + .spannedText(context = context, span = rewardsLockDetails?.description?.span) tvAction.showWhenDataIsAvailable(showText = rewardsLockDetails?.actionData?.title) tvAction.setOnClickListener { actionButtonClickListener?.onCtaClick( @@ -62,4 +64,4 @@ class RewardsLockDetailsBottomSheetView @JvmOverloads constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardsPLUnlockDetailsBottomSheetView.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardsPLUnlockDetailsBottomSheetView.kt index d83714662f..e3e99810d0 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardsPLUnlockDetailsBottomSheetView.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardsPLUnlockDetailsBottomSheetView.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -17,26 +15,26 @@ import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import com.navi.base.model.NaviWidgetClickWithActionData import com.navi.design.utils.dpToPxInInt -import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.design.utils.spannedText +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.naviwidgets.models.response.PLRewardUnlockDetails import com.navi.naviwidgets.utils.NaviWidgetIconUtils.getImageFromIconCode import com.naviapp.R import com.naviapp.databinding.LayoutRewardsPlUnlockDetailsBinding import com.naviapp.rewards.interfaces.ActionButtonClickListener -class RewardsPLUnlockDetailsBottomSheetView @JvmOverloads constructor( - parentContext: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : ConstraintLayout(parentContext, attrs, defStyleAttr) { +class RewardsPLUnlockDetailsBottomSheetView +@JvmOverloads +constructor(parentContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(parentContext, attrs, defStyleAttr) { - private val binding: LayoutRewardsPlUnlockDetailsBinding = DataBindingUtil.inflate( - LayoutInflater.from(context), - R.layout.layout_rewards_pl_unlock_details, - this, - true - ) + private val binding: LayoutRewardsPlUnlockDetailsBinding = + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_rewards_pl_unlock_details, + this, + true + ) private var plRewardUnlockDetails: PLRewardUnlockDetails? = null fun setProperties( @@ -45,40 +43,47 @@ class RewardsPLUnlockDetailsBottomSheetView @JvmOverloads constructor( ) { this.plRewardUnlockDetails = plRewardUnlockDetails binding.apply { - tvTitle.text = plRewardUnlockDetails?.title?.text.spannedText( - context = context, - span = plRewardUnlockDetails?.title?.span - ) - tvDescription.text = plRewardUnlockDetails?.description?.text.spannedText( - context = context, - span = plRewardUnlockDetails?.description?.span - ) - tvEmiTitle.text = plRewardUnlockDetails?.details?.title?.text.spannedText( - context = context, - span = plRewardUnlockDetails?.details?.title?.span - ) + tvTitle.text = + plRewardUnlockDetails + ?.title + ?.text + .spannedText(context = context, span = plRewardUnlockDetails?.title?.span) + tvDescription.text = + plRewardUnlockDetails + ?.description + ?.text + .spannedText(context = context, span = plRewardUnlockDetails?.description?.span) + tvEmiTitle.text = + plRewardUnlockDetails + ?.details + ?.title + ?.text + .spannedText( + context = context, + span = plRewardUnlockDetails?.details?.title?.span + ) binding.plEmiDetails = plRewardUnlockDetails?.details plRewardUnlockDetails?.infoText?.let { tvInfoText.visibility = VISIBLE tvInfoText.text = it.text.spannedText(context = context, span = it.span) - } ?: run { - tvInfoText.visibility = GONE } - tvProvider.showWhenDataIsAvailable(showText = plRewardUnlockDetails?.providerDetails?.text) + ?: run { tvInfoText.visibility = GONE } + tvProvider.showWhenDataIsAvailable( + showText = plRewardUnlockDetails?.providerDetails?.text + ) tvProvider.setCompoundDrawablesWithIntrinsicBounds( 0, 0, if (plRewardUnlockDetails?.providerDetails?.iconUrl.isNullOrEmpty()) { 0 } else { - getImageFromIconCode( - plRewardUnlockDetails?.providerDetails?.iconUrl.orEmpty() - ) + getImageFromIconCode(plRewardUnlockDetails?.providerDetails?.iconUrl.orEmpty()) }, 0 ) viewDottedLine.isVisible = - plRewardUnlockDetails?.showDottedLine != null && plRewardUnlockDetails.showDottedLine == true + plRewardUnlockDetails?.showDottedLine != null && + plRewardUnlockDetails.showDottedLine == true tvAction.showWhenDataIsAvailable(showText = plRewardUnlockDetails?.actionData?.title) if (plRewardUnlockDetails?.actionData?.disabled == true) { tvAction.alpha = 0.56f @@ -105,11 +110,9 @@ class RewardsPLUnlockDetailsBottomSheetView @JvmOverloads constructor( } tvAction.setOnClickListener { actionButtonClickListener.onCtaClick( - NaviWidgetClickWithActionData( - actionData = plRewardUnlockDetails?.actionData - ) + NaviWidgetClickWithActionData(actionData = plRewardUnlockDetails?.actionData) ) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/ui/RewardsUnLockDetailsBottomSheetView.kt b/app/src/main/java/com/naviapp/rewards/ui/RewardsUnLockDetailsBottomSheetView.kt index 68cee251d8..457389569f 100644 --- a/app/src/main/java/com/naviapp/rewards/ui/RewardsUnLockDetailsBottomSheetView.kt +++ b/app/src/main/java/com/naviapp/rewards/ui/RewardsUnLockDetailsBottomSheetView.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -29,18 +27,18 @@ import com.naviapp.R import com.naviapp.databinding.LayoutRewardsUnlockDetailsBinding import com.naviapp.rewards.interfaces.ActionButtonClickListener -class RewardsUnLockDetailsBottomSheetView @JvmOverloads constructor( - parentContext: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : ConstraintLayout(parentContext, attrs, defStyleAttr) { +class RewardsUnLockDetailsBottomSheetView +@JvmOverloads +constructor(parentContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(parentContext, attrs, defStyleAttr) { - private val binding: LayoutRewardsUnlockDetailsBinding = DataBindingUtil.inflate( - LayoutInflater.from(context), - R.layout.layout_rewards_unlock_details, - this, - true - ) + private val binding: LayoutRewardsUnlockDetailsBinding = + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_rewards_unlock_details, + this, + true + ) private var rewardsUnlockDetails: RewardUnlockDetails? = null fun setProperties( @@ -50,61 +48,61 @@ class RewardsUnLockDetailsBottomSheetView @JvmOverloads constructor( this.rewardsUnlockDetails = rewardsUnlockDetails binding.apply { ivIcon.showWhenDataIsAvailable( - imageDetail = ImageDetail( - url = rewardsUnlockDetails?.iconUrl - ) + imageDetail = ImageDetail(url = rewardsUnlockDetails?.iconUrl) ) tvTitle.text = - rewardsUnlockDetails?.title?.text?.spannedText( - context = context, - span = rewardsUnlockDetails.title?.span - ) + rewardsUnlockDetails + ?.title + ?.text + ?.spannedText(context = context, span = rewardsUnlockDetails.title?.span) tvDescription.text = - rewardsUnlockDetails?.description?.text?.spannedText( - context = context, - span = rewardsUnlockDetails.description?.span - ) + rewardsUnlockDetails + ?.description + ?.text + ?.spannedText(context = context, span = rewardsUnlockDetails.description?.span) tvAction.text = rewardsUnlockDetails?.actionData?.title tvAction.setOnClickListener { actionButtonClickListener?.onCtaClick( - NaviWidgetClickWithActionData( - actionData = rewardsUnlockDetails?.actionData - ) + NaviWidgetClickWithActionData(actionData = rewardsUnlockDetails?.actionData) ) } } } fun animateButton(): ObjectAnimator { - val animatorBtn = ObjectAnimator.ofFloat( - binding.tvAction, - Constants.TRANSLATION_Y, - dpToPxInInt(BUTTON_ANIMATION_HEIGHT).toFloat(), - 0f - ) + val animatorBtn = + ObjectAnimator.ofFloat( + binding.tvAction, + Constants.TRANSLATION_Y, + dpToPxInInt(BUTTON_ANIMATION_HEIGHT).toFloat(), + 0f + ) animatorBtn.duration = BUTTON_ANIMATION_DELAY animatorBtn.interpolator = EasingInterpolator(Ease.EASE_IN_OUT_EXPO) - animatorBtn.addListener(object : Animator.AnimatorListener { - override fun onAnimationStart(p0: Animator?) { - binding.tvAction.visibility = VISIBLE + animatorBtn.addListener( + object : Animator.AnimatorListener { + override fun onAnimationStart(p0: Animator?) { + binding.tvAction.visibility = VISIBLE + } + + override fun onAnimationEnd(p0: Animator?) {} + + override fun onAnimationCancel(p0: Animator?) {} + + override fun onAnimationRepeat(p0: Animator?) {} } - - override fun onAnimationEnd(p0: Animator?) {} - - override fun onAnimationCancel(p0: Animator?) {} - - override fun onAnimationRepeat(p0: Animator?) {} - }) + ) return animatorBtn } fun animateView(): ObjectAnimator { - val animatorView = ObjectAnimator.ofFloat( - binding.root, - Constants.TRANSLATION_Y, - dpToPxInInt(VIEW_ANIMATION_HEIGHT).toFloat(), - 0f - ) + val animatorView = + ObjectAnimator.ofFloat( + binding.root, + Constants.TRANSLATION_Y, + dpToPxInInt(VIEW_ANIMATION_HEIGHT).toFloat(), + 0f + ) animatorView.duration = VIEW_ANIMATION_DELAY animatorView.interpolator = EasingInterpolator(Ease.EASE_IN_OUT_EXPO) return animatorView @@ -116,5 +114,4 @@ class RewardsUnLockDetailsBottomSheetView @JvmOverloads constructor( private const val VIEW_ANIMATION_DELAY = 2000L private const val VIEW_ANIMATION_HEIGHT = 80 } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/rewards/views/RewardsTooltipView.kt b/app/src/main/java/com/naviapp/rewards/views/RewardsTooltipView.kt index a59233dbc9..bad9052655 100644 --- a/app/src/main/java/com/naviapp/rewards/views/RewardsTooltipView.kt +++ b/app/src/main/java/com/naviapp/rewards/views/RewardsTooltipView.kt @@ -1,9 +1,7 @@ /* * - * * - * * * Copyright © 2022 by Navi Technologies Private Limited - * * * All rights reserved. Strictly confidential - * * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -28,22 +26,20 @@ import com.naviapp.R import com.naviapp.databinding.LayoutRewardsTooltipBinding import com.naviapp.models.response.RewardsInfo -class RewardsTooltipView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : ConstraintLayout(context, attrs, defStyleAttr) { +class RewardsTooltipView +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { - private val binding: LayoutRewardsTooltipBinding = DataBindingUtil.inflate( - LayoutInflater.from(context), - R.layout.layout_rewards_tooltip, - this, - true - ) + private val binding: LayoutRewardsTooltipBinding = + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.layout_rewards_tooltip, + this, + true + ) - fun update( - rewardsInfo: RewardsInfo? - ) { + fun update(rewardsInfo: RewardsInfo?) { binding.apply { if (rewardsInfo?.enableShimmer == true) { pgvShimmer.isVisible = true @@ -57,33 +53,31 @@ class RewardsTooltipView @JvmOverloads constructor( } else { pgvShimmer.isVisible = false } - ivIcon.showWhenDataIsAvailable( - imageDetail = ImageDetail( - url = rewardsInfo?.iconUrl - ) - ) - tvTitle.text = rewardsInfo?.title?.text.spannedText( - context = context, - span = rewardsInfo?.title?.span - ) + ivIcon.showWhenDataIsAvailable(imageDetail = ImageDetail(url = rewardsInfo?.iconUrl)) + tvTitle.text = + rewardsInfo + ?.title + ?.text + .spannedText(context = context, span = rewardsInfo?.title?.span) tvTag.showWhenDataIsAvailable(showText = rewardsInfo?.tagInfo?.text) tvTag.backgroundTintList = ColorStateList.valueOf(rewardsInfo?.tagInfo?.bgColor.parseColorSafe()) tvTag.setTextColor(rewardsInfo?.tagInfo?.textColor.parseColorSafe()) - clParent.background = ContextCompat.getDrawable( - context, - when (rewardsInfo?.rewardType) { - RewardType.CASH.name -> { - com.navi.naviwidgets.R.drawable.ic_rewards_info_cash_bg + clParent.background = + ContextCompat.getDrawable( + context, + when (rewardsInfo?.rewardType) { + RewardType.CASH.name -> { + com.navi.naviwidgets.R.drawable.ic_rewards_info_cash_bg + } + RewardType.GOLD.name -> { + com.navi.naviwidgets.R.drawable.ic_rewards_info_gold_bg + } + else -> { + com.navi.naviwidgets.R.drawable.ic_rewards_info_cash_bg + } } - RewardType.GOLD.name -> { - com.navi.naviwidgets.R.drawable.ic_rewards_info_gold_bg - } - else -> { - com.navi.naviwidgets.R.drawable.ic_rewards_info_cash_bg - } - } - ) + ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/status_tracker/fragments/TrackerFragment.kt b/app/src/main/java/com/naviapp/status_tracker/fragments/TrackerFragment.kt index ea239d6601..725112a5f4 100644 --- a/app/src/main/java/com/naviapp/status_tracker/fragments/TrackerFragment.kt +++ b/app/src/main/java/com/naviapp/status_tracker/fragments/TrackerFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -33,36 +33,30 @@ import com.naviapp.part_prepayment.states.GenericWidgetState import com.naviapp.personalloan.getloan.common.fragment.CustomerSupportFragment import com.naviapp.status_tracker.view_models.TrackerVM import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import javax.inject.Inject @AndroidEntryPoint class TrackerFragment : BaseFragment(), WidgetCallback { - @Inject - lateinit var widgetIdProvider: WidgetIdProvider + @Inject lateinit var widgetIdProvider: WidgetIdProvider - @Inject - lateinit var actionButtonProvider: ActionButtonProvider - private val trackerVM by lazy { - ViewModelProvider(this).get( - TrackerVM::class.java - ) - } + @Inject lateinit var actionButtonProvider: ActionButtonProvider + private val trackerVM by lazy { ViewModelProvider(this).get(TrackerVM::class.java) } private lateinit var binding: FragmentTrackerBinding - private val naviAdapter = NaviInputWidgetAdapter( - widgetCallback = this, - factory = ViewHolderFactoryImpl() - ) + private val naviAdapter = + NaviInputWidgetAdapter( + widgetCallback = this, + factory = ViewHolderFactoryImpl() + ) override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = DataBindingUtil.inflate( - inflater, R.layout.fragment_tracker, container, false - ) + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_tracker, container, false) return binding.root } @@ -80,13 +74,9 @@ class TrackerFragment : BaseFragment(), WidgetCallback { activity?.onBackPressed() } else { val bundle = Bundle() - naviClickAction.parameters?.forEach { - bundle.putString(it.key, it.value) - } + naviClickAction.parameters?.forEach { bundle.putString(it.key, it.value) } naviClickAction.url?.let { - fragmentInterchangeListener?.navigateToNextScreen( - it, bundle - ) + fragmentInterchangeListener?.navigateToNextScreen(it, bundle) } } } @@ -102,38 +92,24 @@ class TrackerFragment : BaseFragment(), WidgetCallback { private fun init() { viewLifecycleOwner.lifecycleScope.launchWhenStarted { - launch { - trackerVM.fetchData(arguments) - } - launch { - trackerVM.widgetDataResponse.collect { - setWidgetState(it) - } - } + launch { trackerVM.fetchData(arguments) } + launch { trackerVM.widgetDataResponse.collect { setWidgetState(it) } } } } private fun setWidgetState(viewState: GenericWidgetState) { when (viewState) { - is GenericWidgetState.Init -> { - } + is GenericWidgetState.Init -> {} is GenericWidgetState.Update -> { viewState.data?.run { - this.header?.getOrNull(0)?.let { - updateContainer(it, binding.headerContainer) - } + this.header?.getOrNull(0)?.let { updateContainer(it, binding.headerContainer) } - this.footer?.getOrNull(0)?.let { - updateContainer(it, binding.footerContainer) - } + this.footer?.getOrNull(0)?.let { updateContainer(it, binding.footerContainer) } this.content?.let { contentWidget -> binding.recyclerView.apply { - val linearLayoutManager = LinearLayoutManager( - context, - LinearLayoutManager.VERTICAL, - false - ) + val linearLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) layoutManager = linearLayoutManager naviAdapter.list = contentWidget adapter = naviAdapter @@ -141,7 +117,8 @@ class TrackerFragment : BaseFragment(), WidgetCallback { } val analyticsEvent = - this.metadata?.get(PartPrePaymentActivity.METADATA_ANALYTICS_EVENT)?.data as? AnalyticsEvent + this.metadata?.get(PartPrePaymentActivity.METADATA_ANALYTICS_EVENT)?.data + as? AnalyticsEvent NaviAnalytics.naviAnalytics.sendAnalyticsEvent(analyticsEvent, screenName) } } @@ -153,15 +130,14 @@ class TrackerFragment : BaseFragment(), WidgetCallback { safelyShowBottomSheet(bottomSheet, CustomerSupportFragment.TAG) } - private fun updateContainer( - naviWidget: NaviWidget, - container: ViewGroup - ) { + private fun updateContainer(naviWidget: NaviWidget, container: ViewGroup) { viewLifecycleOwner.lifecycleScope.launch { val layoutBinding = container.replaceLayout(widgetIdProvider.getNaviWidgetLayoutId(naviWidget)) (layoutBinding?.root as? BaseNaviWidgetLayout)?.updateLayout( - layoutBinding, naviWidget, this@TrackerFragment + layoutBinding, + naviWidget, + this@TrackerFragment ) } } @@ -172,4 +148,4 @@ class TrackerFragment : BaseFragment(), WidgetCallback { companion object { const val TAG = "TRACKER_SCREEN" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/naviapp/storyview/PausableProgressBar.kt b/app/src/main/java/com/naviapp/storyview/PausableProgressBar.kt index 5abe275719..9f7c5a7cb4 100644 --- a/app/src/main/java/com/naviapp/storyview/PausableProgressBar.kt +++ b/app/src/main/java/com/naviapp/storyview/PausableProgressBar.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.naviapp.storyview import android.content.Context @@ -11,15 +18,13 @@ import android.view.animation.ScaleAnimation import android.view.animation.Transformation import android.widget.FrameLayout import androidx.annotation.AttrRes +import com.navi.common.utils.setCornerRadius import com.naviapp.R -import com.naviapp.utils.setCornerRadius - -class PausableProgressBar @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - @AttrRes defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr) { +class PausableProgressBar +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) : + FrameLayout(context, attrs, defStyleAttr) { private var frontProgressView: View? = null private var maxProgressView: View? = null private var animation: PausableScaleAnimation? = null @@ -38,7 +43,6 @@ class PausableProgressBar @JvmOverloads constructor( fun onFinishProgress() } - fun setDuration(duration: Long) { this.duration = duration } @@ -61,7 +65,6 @@ class PausableProgressBar @JvmOverloads constructor( animation?.setAnimationListener(null) animation?.cancel() - } fun setMaxWithoutCallback() { @@ -94,17 +97,19 @@ class PausableProgressBar @JvmOverloads constructor( ) animation?.duration = duration animation?.interpolator = LinearInterpolator() - animation?.setAnimationListener(object : Animation.AnimationListener { - override fun onAnimationStart(animation: Animation) { - frontProgressView?.visibility = VISIBLE - callback?.onStartProgress() - } + animation?.setAnimationListener( + object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation) { + frontProgressView?.visibility = VISIBLE + callback?.onStartProgress() + } - override fun onAnimationRepeat(animation: Animation) {} - override fun onAnimationEnd(animation: Animation) { - callback?.onFinishProgress() + override fun onAnimationRepeat(animation: Animation) {} + override fun onAnimationEnd(animation: Animation) { + callback?.onFinishProgress() + } } - }) + ) animation?.fillAfter = true frontProgressView?.startAnimation(animation) } @@ -121,18 +126,19 @@ class PausableProgressBar @JvmOverloads constructor( animation?.setAnimationListener(null) animation?.cancel() animation = null - } - private inner class PausableScaleAnimation internal constructor( - fromX: Float, toX: Float, fromY: Float, - toY: Float, pivotXType: Int, pivotXValue: Float, pivotYType: Int, + private inner class PausableScaleAnimation + internal constructor( + fromX: Float, + toX: Float, + fromY: Float, + toY: Float, + pivotXType: Int, + pivotXValue: Float, + pivotYType: Int, pivotYValue: Float - ) : - ScaleAnimation( - fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, - pivotYValue - ) { + ) : ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue) { private var mElapsedAtPause: Long = 0 private var mPaused = false override fun getTransformation( @@ -149,7 +155,6 @@ class PausableProgressBar @JvmOverloads constructor( return super.getTransformation(currentTime, outTransformation, scale) } - fun pause() { if (mPaused) return mElapsedAtPause = 0 @@ -165,6 +170,4 @@ class PausableProgressBar @JvmOverloads constructor( private const val DEFAULT_PROGRESS_DURATION = 2000 } - - } diff --git a/app/src/main/java/com/naviapp/utils/BindingAdapterUtil.kt b/app/src/main/java/com/naviapp/utils/BindingAdapterUtil.kt index 497f3b591d..b8754f7e78 100644 --- a/app/src/main/java/com/naviapp/utils/BindingAdapterUtil.kt +++ b/app/src/main/java/com/naviapp/utils/BindingAdapterUtil.kt @@ -42,6 +42,7 @@ import com.navi.common.listeners.ClickableTextListener import com.navi.common.model.Money import com.navi.common.model.StyledTextWithIconCode import com.navi.common.utils.log +import com.navi.common.utils.makePartOfTextBold import com.navi.common.utils.orTrue import com.navi.common.utils.spannableString import com.navi.design.textview.NaviTextView @@ -53,8 +54,8 @@ import com.navi.design.utils.setSpannableString import com.navi.naviwidgets.extensions.isValidHexColor import com.navi.naviwidgets.extensions.setSpannableString import com.navi.naviwidgets.models.response.BottomSheetSubListData -import com.navi.naviwidgets.models.response.SelectableItemData import com.navi.naviwidgets.models.response.GenericBottomSheetLineData +import com.navi.naviwidgets.models.response.SelectableItemData import com.navi.naviwidgets.utils.NaviWidgetIconUtils import com.navi.naviwidgets.widgets.textdisplay.Margin import com.naviapp.R @@ -656,8 +657,7 @@ object BindingAdapterUtil { val loanDetailItemView = LayoutInflater.from(linearLayout.context) .inflate(R.layout.view_hl_tracker_key_value_item, linearLayout, false) - val viewLoanDetailItemBinding: - com.naviapp.databinding.ViewHlTrackerKeyValueItemBinding? = + val viewLoanDetailItemBinding: ViewHlTrackerKeyValueItemBinding? = DataBindingUtil.bind(loanDetailItemView) viewLoanDetailItemBinding?.keyTv?.text = value.title viewLoanDetailItemBinding?.valueTv?.text = value.text @@ -808,35 +808,6 @@ object BindingAdapterUtil { .root } - // TODO Create a generic version here - @BindingAdapter("setStyledText", "setClickableTextListener", requireAll = false) - @JvmStatic - fun setStyledText( - textView: TextView, - styledTextWithIconCode: StyledTextWithIconCode?, - clickableTextListener: ClickableTextListener? - ) { - styledTextWithIconCode?.let { - it.text?.let { text -> textView.text = text } - it.hexColorCode?.let { hexColorCode -> - try { - textView.setTextColor(Color.parseColor(hexColorCode)) - } catch (e: Exception) { - e.log() - } - } - - it.boldText?.let { boldText -> - it.text?.let { text -> textView.makePartOfTextBold(text, boldText) } - } - it.boldTextList?.let { boldText -> - it.text?.let { text -> textView.makePartOfTextBold(text, boldText) } - } - - textView.spannableString(it, clickableTextListener) - } - } - @BindingAdapter("setRowData") @JvmStatic fun setRowData(linearLayout: LinearLayout, items: List?) { diff --git a/app/src/main/java/com/naviapp/utils/Constants.kt b/app/src/main/java/com/naviapp/utils/Constants.kt index 21e0e260a8..7f79434af4 100644 --- a/app/src/main/java/com/naviapp/utils/Constants.kt +++ b/app/src/main/java/com/naviapp/utils/Constants.kt @@ -150,6 +150,7 @@ object Constants { const val FIVE_MINUTES_TO_SEC = (300 * MILLISECONDS_PER_SECOND).toLong() const val SA = "sa" const val URL = "url" + const val CALL_ENABLED = "CALL_ENABLED" const val ADDITIONAL_DATA_NEEDED = "additional_data_needed" const val IS_PUBLIC_PAGE = "is_public_page" const val CONSENT_IDENTIFIER_CATEGORY = "STRONG" @@ -282,6 +283,7 @@ object Constants { const val IS_INSTALMENT = "isInstallment" const val INSTALMENT_DATE = "installmentDate" const val GRID_OPTION_BOTTOMSHEET = "grid_option_bottomsheet" + const val VALIDITY_INFO_BOTTOM_SHEET = "validity_info_bottomsheet" const val BOTTOMSHEET_SELECT_POLICY = "bottomsheet_select_policy" const val GI_CLAIMS_BOTTOMSHEET = "gi_claims_bottomsheet" const val SPACE = " " @@ -298,7 +300,6 @@ object Constants { const val FRESH_LOAN_DETAILS_FLOW = "FRESH_LOAN_DETAILS_FLOW" const val OFFER_GENERATION_FLOW = "OFFER_GENERATION" const val OFFER_UPGRADE_FLOW = "OFFER_UPGRADE" - const val EXPIRY_TIME_IN_MIN = "expiryTimeInMinutes" const val NOTIFICATION_SENT_TIME = "notificationSentTimeInUTC" const val SOURCE = "source" diff --git a/app/src/main/java/com/naviapp/utils/IconUtils.kt b/app/src/main/java/com/naviapp/utils/IconUtils.kt index e3b3927b9d..8178bc0ce6 100644 --- a/app/src/main/java/com/naviapp/utils/IconUtils.kt +++ b/app/src/main/java/com/naviapp/utils/IconUtils.kt @@ -381,7 +381,7 @@ object IconUtils { ADDRESS_LARGE -> R.drawable.ic_pincode ICON_CLOCK -> R.drawable.ic_dark_clock_svg ICON_UP_ARROW -> R.drawable.ic_home_up_arrow_svg - ICON_CAMERA -> R.drawable.ic_camera_svg + ICON_CAMERA -> R.drawable.vkyc_camera_svg COUPLE_INVEST_COIN_ICON -> R.drawable.ic_couple_money EMAIL_LOAN_ICON -> R.drawable.ic_loan_email EMAIL_MF_ICON -> R.drawable.ic_mf_email diff --git a/app/src/main/java/com/naviapp/utils/MockUtil.kt b/app/src/main/java/com/naviapp/utils/MockUtil.kt index 937a611c51..c0da96aba1 100644 --- a/app/src/main/java/com/naviapp/utils/MockUtil.kt +++ b/app/src/main/java/com/naviapp/utils/MockUtil.kt @@ -10,6 +10,7 @@ package com.naviapp.utils import com.google.gson.GsonBuilder import com.google.gson.JsonObject import com.google.gson.JsonParser +import com.navi.common.model.RepoResult import com.navi.naviwidgets.models.NaviWidget import com.navi.naviwidgets.models.ParameterValue import com.navi.naviwidgets.validations.BaseInputValidation @@ -18,10 +19,9 @@ import com.navi.naviwidgets.widgets.NaviWidgetJsonDeserializer import com.navi.naviwidgets.widgets.ParameterValueJsonDeserializer import com.naviapp.R import com.naviapp.app.NaviApplication -import com.naviapp.models.response.WidgetConfig -import com.navi.common.model.RepoResult import com.naviapp.homeloandigital.models.response.HomeLoanSubStepResponse import com.naviapp.homeloandigital.tracker.network.HomeLoanTrackerSubStepWidgetDeserializer +import com.naviapp.models.response.WidgetConfig import java.lang.reflect.Type import java.nio.charset.StandardCharsets diff --git a/app/src/main/res/drawable/ic_home_loan.xml b/app/src/main/res/drawable/ic_home_loan.xml index fd091ac489..0477214cae 100644 --- a/app/src/main/res/drawable/ic_home_loan.xml +++ b/app/src/main/res/drawable/ic_home_loan.xml @@ -10,9 +10,9 @@ android:height="88dp" android:viewportWidth="75" android:viewportHeight="88"> - + diff --git a/app/src/main/res/drawable/icon_checkbox_orange.xml b/app/src/main/res/drawable/icon_checkbox_orange.xml index b196c21666..352a07b8b1 100644 --- a/app/src/main/res/drawable/icon_checkbox_orange.xml +++ b/app/src/main/res/drawable/icon_checkbox_orange.xml @@ -7,6 +7,6 @@ --> - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_cross_sell.xml b/app/src/main/res/layout/activity_cross_sell.xml index f113946c1c..1d20b644e1 100644 --- a/app/src/main/res/layout/activity_cross_sell.xml +++ b/app/src/main/res/layout/activity_cross_sell.xml @@ -25,6 +25,30 @@ + + + + + + app:layout_constraintTop_toBottomOf="@id/header_view" /> @@ -193,6 +194,18 @@ + + + - @@ -10,7 +10,13 @@ android:id="@+id/net_banking_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentStart="true"> + android:layout_alignParentStart="true" + android:layout_marginEnd="8dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/otp_banking_container" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> - + diff --git a/app/src/main/res/layout/emi_date_change_fragment.xml b/app/src/main/res/layout/emi_date_change_fragment.xml index 9d27f9c0ec..feb922aba9 100644 --- a/app/src/main/res/layout/emi_date_change_fragment.xml +++ b/app/src/main/res/layout/emi_date_change_fragment.xml @@ -59,20 +59,62 @@ android:layout_marginStart="@dimen/layout_dp_10" android:layout_marginEnd="@dimen/layout_dp_10" app:layout_constraintTop_toBottomOf="@id/choose_emi_date_tv" - app:layout_constraintBottom_toTopOf="@id/enter_reason_lt" + app:layout_constraintBottom_toTopOf="@id/reason_layout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" tools:itemCount="3" tools:listitem="@layout/emi_date_item" /> - + app:layout_constraintBottom_toTopOf="@id/footer_view"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/grid_option_bottomsheet_layout.xml b/app/src/main/res/layout/grid_option_bottomsheet_layout.xml index 432eb1ad76..74fa79a1b1 100644 --- a/app/src/main/res/layout/grid_option_bottomsheet_layout.xml +++ b/app/src/main/res/layout/grid_option_bottomsheet_layout.xml @@ -8,6 +8,30 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + + + + tools:listitem="@layout/grid_option_item" + tools:spanCount="3" /> \ No newline at end of file diff --git a/app/src/main/res/layout/gst_item_layout.xml b/app/src/main/res/layout/gst_item_layout.xml index 12e065f676..bab7d296f5 100644 --- a/app/src/main/res/layout/gst_item_layout.xml +++ b/app/src/main/res/layout/gst_item_layout.xml @@ -26,7 +26,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:text="29AACCF0683K1ZD" /> + tools:text="29AAECC7456R1ZD" /> diff --git a/app/src/main/res/layout/kyc_pan_view.xml b/app/src/main/res/layout/kyc_pan_view.xml index cf759b4de4..4d0f489da1 100644 --- a/app/src/main/res/layout/kyc_pan_view.xml +++ b/app/src/main/res/layout/kyc_pan_view.xml @@ -87,7 +87,7 @@ android:adjustViewBounds="true" android:background="@color/red" android:padding="@dimen/layout_dp_12" - android:src="@drawable/ic_camera_svg" + android:src="@drawable/vkyc_camera_svg" tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/mandatory_permission_banner_layout.xml b/app/src/main/res/layout/mandatory_permission_banner_layout.xml index 54a6bfc207..2091f3d1c8 100644 --- a/app/src/main/res/layout/mandatory_permission_banner_layout.xml +++ b/app/src/main/res/layout/mandatory_permission_banner_layout.xml @@ -8,7 +8,7 @@ + type="com.navi.common.model.permission.PermissionTile" /> + type="com.navi.common.model.permission.PermissionTile" /> + type="com.navi.common.model.permission.PermissionTile" /> diff --git a/app/src/main/res/layout/select_bank_v2_layout.xml b/app/src/main/res/layout/select_bank_v2_layout.xml index e1398af06f..2a5d073b39 100644 --- a/app/src/main/res/layout/select_bank_v2_layout.xml +++ b/app/src/main/res/layout/select_bank_v2_layout.xml @@ -18,6 +18,7 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/raw/mock.json b/app/src/main/res/raw/mock.json index 9e26dfeeb6..e69de29bb2 100644 --- a/app/src/main/res/raw/mock.json +++ b/app/src/main/res/raw/mock.json @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 852c9b5152..5274ba17b2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -413,6 +413,8 @@ You will receive otp via call All Supported Banks This bank is not supported. Kindly select some other bank. + This bank is not supported. + Kindly select some other bank. My Loans Insurance @@ -1118,4 +1120,5 @@ Due: Rewards on your way! Documents + Check loan offer diff --git a/app/src/test/java/com/naviapp/mock_setup/MockSetupHelper.kt b/app/src/test/java/com/naviapp/mock_setup/MockSetupHelper.kt index 6eb58c991a..9cd1b51059 100644 --- a/app/src/test/java/com/naviapp/mock_setup/MockSetupHelper.kt +++ b/app/src/test/java/com/naviapp/mock_setup/MockSetupHelper.kt @@ -33,7 +33,7 @@ object MockSetupHelper { } - /** You must use name as Veerendra kumar and correct PAN = 'AENPK0575P' for this mock to work properly */ + /** You must use name as Veerendra kumar and correct PAN = 'AAAAA1234A' for this mock to work properly */ fun enableNSDlMock(mockType: NSDLMockType): Pair = doMockSetup(mockType) diff --git a/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanPanVMTest.kt b/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanPanVMTest.kt index dcfad6b768..fe1b37f26e 100644 --- a/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanPanVMTest.kt +++ b/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanPanVMTest.kt @@ -64,7 +64,7 @@ class PersonalLoanPanVMTest { progress = 90 ), content = UserDetail( - panNumber = "MKGYP1090K" + panNumber = "AAAAA1234A" ), footer = Footer( backCta = CtaData(title = null, url = "WORK_DETAILS"), @@ -99,7 +99,7 @@ class PersonalLoanPanVMTest { viewModel.panDataResponse.value?.footer?.nextCta?.title ) Assert.assertEquals( - "MKGYP1090K", + "AAAAA1234A", viewModel.panDataResponse.value?.content?.panNumber ) } @@ -117,14 +117,14 @@ class PersonalLoanPanVMTest { ) val response = RepoResult(mockData) val panRequest = PanRequest( - panNumber = "BFWPB0281G", + panNumber = "AAAAA1234A", dateOfBirth = "01-01-1994", pinCode = "560017", skipValidation = false ) coEvery { repository.submitPanDetails(panRequest) } returns response viewModel.submitPanDetails( - panNumber = "BFWPB0281G", + panNumber = "AAAAA1234A", dob = "01-01-1994", pinCode = "560017", skipValidation = false diff --git a/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanProfileVMTest.kt b/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanProfileVMTest.kt index f2f992537a..5480f8ffb5 100644 --- a/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanProfileVMTest.kt +++ b/app/src/test/java/com/naviapp/personalloan/eligibility/viewmodel/PersonalLoanProfileVMTest.kt @@ -139,7 +139,7 @@ class PersonalLoanProfileVMTest { pinCode = "100006", skipValidation = false, customerRelations = null, - panNumber = "HHHHH1234H" + panNumber = "AAAAA1234A" ) coEvery { repository.submitProfileDetails(profileRequest,"prevPageDummy") } returns response viewModel.submitProfileDetails( @@ -148,7 +148,7 @@ class PersonalLoanProfileVMTest { maritalStatus = "MARRIED", pinCode = "100006", skipValidation = false, - panNumber = "HHHHH1234H", + panNumber = "AAAAA1234A", prevPage = "prevPageDummy" ) Assert.assertEquals( diff --git a/digio-kyc-3.1.5/build.gradle b/digio-kyc-3.1.5/build.gradle deleted file mode 100644 index d25a2c00d0..0000000000 --- a/digio-kyc-3.1.5/build.gradle +++ /dev/null @@ -1,2 +0,0 @@ -configurations.maybeCreate("default") -artifacts.add("default", file('digio-kyc-3.1.5.aar')) \ No newline at end of file diff --git a/digio-kyc-3.1.5/digio-kyc-3.1.5.aar b/digio-kyc-3.1.5/digio-kyc-3.1.5.aar deleted file mode 100644 index c1be6ae7b5..0000000000 Binary files a/digio-kyc-3.1.5/digio-kyc-3.1.5.aar and /dev/null differ diff --git a/digio-kyc-3.1.7/build.gradle b/digio-kyc-3.1.7/build.gradle new file mode 100644 index 0000000000..464c3e40d9 --- /dev/null +++ b/digio-kyc-3.1.7/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('digio-kyc-3.1.7.aar')) \ No newline at end of file diff --git a/digio-kyc-3.1.7/digio-kyc-3.1.7.aar b/digio-kyc-3.1.7/digio-kyc-3.1.7.aar new file mode 100644 index 0000000000..eabe86a5ac Binary files /dev/null and b/digio-kyc-3.1.7/digio-kyc-3.1.7.aar differ diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 0000000000..2a44413257 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,2 @@ +json_key_file("api-credentials.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one +package_name("com.naviapp") # e.g. com.krausefx.app diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000000..35dfde7fbd --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,46 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:android) + +platform :android do + + # desc "Deploy a new version to the Google Play" + # lane :deploy_to_play_store do + # upload_to_play_store( + # skip_upload_apk: 'true', + # skip_upload_aab: 'false', + # skip_upload_metadata: 'true', + # skip_upload_changelogs: 'false', + # skip_upload_images: 'true', + # skip_upload_screenshots: 'true', + # apk: 'app/build/outputs/bundle/prodRelease/app-prod-release.aab', + # rollout: '0.05' + # ) + # end + + desc "Increase rollout in production track" + lane :increase_rollout do |options| + upload_to_play_store( + skip_upload_apk: 'true', + skip_upload_aab: 'true', + skip_upload_metadata: 'true', + skip_upload_changelogs: 'true', + skip_upload_images: 'true', + skip_upload_screenshots: 'true', + rollout: options[:rollout] + ) + end +end diff --git a/navi-amc/src/main/java/com/navi/amc/common/activity/CheckerActivity.kt b/navi-amc/src/main/java/com/navi/amc/common/activity/CheckerActivity.kt index 0496bc2b53..e4868b0a61 100644 --- a/navi-amc/src/main/java/com/navi/amc/common/activity/CheckerActivity.kt +++ b/navi-amc/src/main/java/com/navi/amc/common/activity/CheckerActivity.kt @@ -229,10 +229,11 @@ class CheckerActivity : BasePaymentActivity() { private fun onFailureResponse(response: GenericErrorResponse?) { response?.let { + apiPollScheduler?.stopApiPoll() + val url = getCta() val bundle = intent.extras ?: Bundle() bundle.putParcelable(ERROR_DATA, it) - apiPollScheduler?.stopApiPoll() - ActionData(url = getCta()).toNavigateAmcModule(this, finish = true, bundle = bundle) + ActionData(url = url).toNavigateAmcModule(this, finish = true, bundle = bundle) } } diff --git a/navi-amc/src/main/java/com/navi/amc/fundbuy/activities/FundBuyActivity.kt b/navi-amc/src/main/java/com/navi/amc/fundbuy/activities/FundBuyActivity.kt index 071ea505bd..9f9f3cf41e 100644 --- a/navi-amc/src/main/java/com/navi/amc/fundbuy/activities/FundBuyActivity.kt +++ b/navi-amc/src/main/java/com/navi/amc/fundbuy/activities/FundBuyActivity.kt @@ -7,6 +7,7 @@ import com.navi.amc.common.activity.AmcBaseActivity import com.navi.amc.common.listener.BackListener import com.navi.amc.databinding.FundBuyActivityBinding import com.navi.amc.navigator.NaviAmcDeeplinkNavigator +import com.navi.amc.navigator.NaviAmcDeeplinkNavigator.CHECKER import com.navi.amc.navigator.NaviAmcDeeplinkNavigator.KYC import com.navi.amc.utils.* import com.navi.base.model.ActionData @@ -74,13 +75,22 @@ class FundBuyActivity : AmcBaseActivity(), FragmentInterchangeListener, HeaderIn } } else { actionData?.url?.let { - actionData.toNavigateAmcModule(this, finish = currentScreenTag.contains(KYC).not(), bundle = bundle) + actionData.toNavigateAmcModule(this, finish = toFinishActivity(currentScreenTag), bundle = bundle) } ?: kotlin.run { onBackPressed() } } } + private fun toFinishActivity(screenName: String): Boolean { + val screens = listOf(KYC, CHECKER) + screens.forEach { + if (screenName.contains(it, true)) + return false + } + return true + } + override fun setProperties(header: Header?) { binding.headerView.setProperties(header, this) } diff --git a/navi-amc/src/main/java/com/navi/amc/fundbuy/fragments/FundDetailsFragment.kt b/navi-amc/src/main/java/com/navi/amc/fundbuy/fragments/FundDetailsFragment.kt index e674c69fe9..8039194c69 100644 --- a/navi-amc/src/main/java/com/navi/amc/fundbuy/fragments/FundDetailsFragment.kt +++ b/navi-amc/src/main/java/com/navi/amc/fundbuy/fragments/FundDetailsFragment.kt @@ -36,6 +36,7 @@ import com.navi.amc.utils.Constant.DATA import com.navi.amc.utils.Constant.SHOW_BOTTOMSHEET import com.navi.amc.utils.getBottomSheet import com.navi.amc.utils.orFalse +import com.navi.amc.utils.orTrue import com.navi.base.model.ActionData import com.navi.base.utils.BaseUtils.cacheDirUri import com.navi.common.downloader.DownloadUtil @@ -101,8 +102,8 @@ class FundDetailsFragment : AmcBaseFragment() { val rect = Rect() scroll.getHitRect(rect) val view = - binding.container.findViewWithTag("graph").getSubtitle() - if (!view.getLocalVisibleRect(rect)) { + binding.container.findViewWithTag("graph")?.getSubtitle() + if (!view?.getLocalVisibleRect(rect).orTrue()) { binding.fundOnscrollView.apply { left.setSpannableString(viewModel.fundReturn.value?.leftText) right.setSpannableString(viewModel.fundReturn.value?.rightText) diff --git a/navi-base/src/main/java/com/navi/base/model/NaviClickAction.kt b/navi-base/src/main/java/com/navi/base/model/NaviClickAction.kt index 824ebc7b62..a8879cc77b 100644 --- a/navi-base/src/main/java/com/navi/base/model/NaviClickAction.kt +++ b/navi-base/src/main/java/com/navi/base/model/NaviClickAction.kt @@ -27,6 +27,7 @@ data class InputTextClickAction( data class ActionData( @SerializedName("screenName") val screenName: String? = null, @SerializedName("url") val url: String? = null, + @SerializedName("type") val type: String? = null, @SerializedName("title") val title: String? = null, @SerializedName("description") val description: String? = null, @SerializedName("primaryAction") val primaryAction: ActionData? = null, @@ -42,6 +43,9 @@ data class ActionData( data class NaviWidgetInfoClick(val widgetId: String? = null) : NaviClickAction() +data class NaviBenefitsItemClick(val ctaData: CtaData? = null, val position: Int) : + NaviClickAction() + data class NaviWidgetClickWithActionData( val widgetId: String? = null, val widgetName: String? = null, @@ -49,6 +53,12 @@ data class NaviWidgetClickWithActionData( val isFinish: Boolean = false ) : NaviClickAction() +data class NaviWidgetClickWithCtaData( + val widgetId: String? = null, + val widgetName: String? = null, + val ctaData: CtaData? = null +) : NaviClickAction() + enum class CtaType(val value: String?) { DONE_CTA("DONE_CTA"), NAVIGATE_TO_NEW_SCREEN("NAVIGATE_TO_NEW_SCREEN"), @@ -74,6 +84,7 @@ enum class CtaType(val value: String?) { UPDATE_WIDGET("UPDATE_WIDGET"), PAYMENT_INFO_BOTTOM_SHEET("PAYMENT_INFO_BOTTOM_SHEET"), GO_BACK("GO_BACK"), + GO_TO_DASHBOARD("GO_TO_DASHBOARD"), CLOSE_BOTTOM_SHEET("CLOSE_BOTTOM_SHEET"), TERMS_AND_CONDITIONS_BOTTOM_SHEET("TERMS_AND_CONDITIONS_BOTTOM_SHEET"), CLOSE_SCREEN("CLOSE_SCREEN"), @@ -82,5 +93,6 @@ enum class CtaType(val value: String?) { ADD_MEMBERS_BOTTOM_SHEET("ADD_MEMBERS_BOTTOM_SHEET"), RE_ADD_MEMBER_BOTTOM_SHEET("RE_ADD_MEMBER_BOTTOM_SHEET"), RE_ADD_MEMBER_API("RE_ADD_MEMBER_API"), - PAYMENT_DETAILS_API("PAYMENT_DETAILS_API") + PAYMENT_DETAILS_API("PAYMENT_DETAILS_API"), + USE_ROOT_DEEPLINK_NAVIGATOR("USE_ROOT_DEEPLINK_NAVIGATOR") } diff --git a/navi-chat/src/main/java/com/navi/chat/data/firestore/ChatFireStoreDatabase.kt b/navi-chat/src/main/java/com/navi/chat/data/firestore/ChatFireStoreDatabase.kt index 8cf4f8411c..79a9dcb371 100644 --- a/navi-chat/src/main/java/com/navi/chat/data/firestore/ChatFireStoreDatabase.kt +++ b/navi-chat/src/main/java/com/navi/chat/data/firestore/ChatFireStoreDatabase.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.chat.data.firestore import com.google.firebase.Timestamp @@ -13,11 +14,9 @@ import com.google.firebase.firestore.Query import com.navi.chat.db.utils.convertMapToJson import com.navi.chat.db.utils.transformFirestoreToWidgetModel import com.navi.chat.provider.MessageOperation +import com.navi.chat.utils.TYPING_CUES_PATH_AGENT import com.navi.naviwidgets.models.NaviChatWidget -import com.navi.naviwidgets.models.response.NaviChatControllerWidget -import com.navi.naviwidgets.models.response.NaviChatCsatRatingWidget -import com.navi.naviwidgets.models.response.NaviChatCsatUserResponse -import com.navi.naviwidgets.models.response.NaviChatFileAttachmentWidget +import com.navi.naviwidgets.models.response.* import com.navi.naviwidgets.utils.NAVI_CHAT_RT_CREATED_AT import com.navi.naviwidgets.utils.NAVI_CHAT_WIDGET_NAME import timber.log.Timber @@ -31,19 +30,24 @@ class ChatFireStoreDatabase { naviChatWidget: NaviChatWidget, messageOperation: MessageOperation, ) { - ChatFireStore - .getFireStoreReference(path) + ChatFireStore.getFireStoreReference(path) .add(naviChatWidget) .addOnSuccessListener { listenerToFirestoreChangesList.add( it.addSnapshotListener { value, _ -> value?.data?.let { data -> - if (data[NAVI_CHAT_WIDGET_NAME] == NaviChatFileAttachmentWidget.WIDGET_NAME) { + if ( + data[NAVI_CHAT_WIDGET_NAME] == + NaviChatFileAttachmentWidget.WIDGET_NAME + ) { messageOperation.updateTimestamp( transformFirestoreToWidgetModel(data) ) - } else if (data[NAVI_CHAT_WIDGET_NAME] != NaviChatCsatUserResponse.WIDGET_NAME && - data[NAVI_CHAT_WIDGET_NAME] != NaviChatFileAttachmentWidget.WIDGET_NAME + } else if ( + data[NAVI_CHAT_WIDGET_NAME] != + NaviChatCsatUserResponse.WIDGET_NAME && + data[NAVI_CHAT_WIDGET_NAME] != + NaviChatFileAttachmentWidget.WIDGET_NAME ) { Timber.d("Adding new msg from writeToFireStore") messageOperation.addNewMessage( @@ -53,7 +57,8 @@ class ChatFireStoreDatabase { } } ) - }.addOnFailureListener { + } + .addOnFailureListener { Timber.e("Not able to add message $naviChatWidget to firestore") } } @@ -63,52 +68,63 @@ class ChatFireStoreDatabase { latestMessageTimeStamp: Timestamp?, messageOperation: MessageOperation, ) { - ChatFireStore - .getFireStoreReference(path) + ChatFireStore.getFireStoreReference(path) .orderBy(NAVI_CHAT_RT_CREATED_AT, Query.Direction.ASCENDING) .get() .addOnSuccessListener { listenerToFirestoreChangesList.add( if (latestMessageTimeStamp != null) { - Timber.d("Latest timestamp is not null: $latestMessageTimeStamp") - ChatFireStore - .getFireStoreReference(path) - .orderBy(NAVI_CHAT_RT_CREATED_AT) - .startAfter( - Timestamp( - latestMessageTimeStamp.toDate() - ) - ) - } else { - ChatFireStore - .getFireStoreReference(path) - .orderBy(NAVI_CHAT_RT_CREATED_AT, Query.Direction.ASCENDING) - } + Timber.d("Latest timestamp is not null: $latestMessageTimeStamp") + ChatFireStore.getFireStoreReference(path) + .orderBy(NAVI_CHAT_RT_CREATED_AT) + .startAfter(Timestamp(latestMessageTimeStamp.toDate())) + } else { + ChatFireStore.getFireStoreReference(path) + .orderBy(NAVI_CHAT_RT_CREATED_AT, Query.Direction.ASCENDING) + } .addSnapshotListener { value, errorEx -> if (errorEx != null) { return@addSnapshotListener } - for (dc in value!!.documentChanges) { - when (dc.type) { - DocumentChange.Type.ADDED -> { - if (dc.document.data[NAVI_CHAT_WIDGET_NAME] == NaviChatCsatRatingWidget.WIDGET_NAME) { - messageOperation.showFeedbackFragment( - convertMapToJson(dc.document.data) as NaviChatCsatRatingWidget - ) - } else if (dc.document.data[NAVI_CHAT_WIDGET_NAME] == NaviChatControllerWidget.WIDGET_NAME) { - messageOperation.processControllerWidget( - convertMapToJson(dc.document.data) as NaviChatControllerWidget - ) - } else { - Timber.d("Adding new msg from listenToFirestoreChanges") - messageOperation.addNewMessage( - transformFirestoreToWidgetModel(dc.document.data) - ) + value?.let { + for (dc in value.documentChanges) { + when (dc.type) { + DocumentChange.Type.ADDED -> { + if ( + dc.document.data[NAVI_CHAT_WIDGET_NAME] == + NaviChatCsatRatingWidget.WIDGET_NAME + ) { + messageOperation.showFeedbackFragment( + convertMapToJson( + dc.document.data + ) + as NaviChatCsatRatingWidget + ) + } else if ( + dc.document.data[NAVI_CHAT_WIDGET_NAME] == + NaviChatControllerWidget.WIDGET_NAME + ) { + messageOperation.processControllerWidget( + convertMapToJson( + dc.document.data + ) + as NaviChatControllerWidget + ) + } else { + Timber.d( + "Adding new msg from listenToFirestoreChanges" + ) + messageOperation.addNewMessage( + transformFirestoreToWidgetModel( + dc.document.data + ) + ) + } } + DocumentChange.Type.MODIFIED -> {} + DocumentChange.Type.REMOVED -> {} } - DocumentChange.Type.MODIFIED -> {} - DocumentChange.Type.REMOVED -> {} } } } @@ -116,6 +132,49 @@ class ChatFireStoreDatabase { } } + fun listenToFireStoreListenerForMessageStatus( + path: String, + messageOperation: MessageOperation + ) { + ChatFireStore.getFireStoreReference(path).get().addOnSuccessListener { + listenerToFirestoreChangesList.add( + ChatFireStore.getFireStoreReference(path).addSnapshotListener { value, errorEx -> + if (errorEx != null) { + return@addSnapshotListener + } + + value?.let { + for (dc in value.documentChanges) { + when (dc.type) { + DocumentChange.Type.ADDED -> { + if (dc.document.id == TYPING_CUES_PATH_AGENT) { + messageOperation.updateTypingStatus( + convertMapToJson( + dc.document.data + ) + as NaviChatTypingStatusWidget + ) + } + } + DocumentChange.Type.MODIFIED -> { + if (dc.document.id == TYPING_CUES_PATH_AGENT) { + messageOperation.updateTypingStatus( + convertMapToJson( + dc.document.data + ) + as NaviChatTypingStatusWidget + ) + } + } + DocumentChange.Type.REMOVED -> {} + } + } + } + } + ) + } + } + fun removeFireStoreListener() { if (listenerToFirestoreChangesList.size > 0) { for (listener in listenerToFirestoreChangesList) { @@ -127,4 +186,4 @@ class ChatFireStoreDatabase { companion object { const val TAG = "ChatFireStoreDatabase" } -} \ No newline at end of file +} diff --git a/navi-chat/src/main/java/com/navi/chat/models/FireStoreDataProviderModel.kt b/navi-chat/src/main/java/com/navi/chat/models/FireStoreDataProviderModel.kt index 4bcf01fc23..82f4f35ea5 100644 --- a/navi-chat/src/main/java/com/navi/chat/models/FireStoreDataProviderModel.kt +++ b/navi-chat/src/main/java/com/navi/chat/models/FireStoreDataProviderModel.kt @@ -1,13 +1,15 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.chat.models data class FireStoreDataProviderModel( override val chatProviderName: String, val readPath: String, - val writePath: String + val writePath: String, + val eventsPath: String ) : ChatDataProviderModel diff --git a/navi-chat/src/main/java/com/navi/chat/models/response/NaviChatInitiateResponse.kt b/navi-chat/src/main/java/com/navi/chat/models/response/NaviChatInitiateResponse.kt index 60a898bcbe..0d2df6dfba 100644 --- a/navi-chat/src/main/java/com/navi/chat/models/response/NaviChatInitiateResponse.kt +++ b/navi-chat/src/main/java/com/navi/chat/models/response/NaviChatInitiateResponse.kt @@ -1,20 +1,18 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.chat.models.response import com.google.gson.annotations.SerializedName data class NaviChatInitiateResponse( - @SerializedName("conversation_id") - val conversationId: String? = null, - @SerializedName("read_path") - val readPath: String? = null, - @SerializedName("write_path") - val writePath: String? = null, - @SerializedName("show_textbox") - val showFreeText: Boolean? = null + @SerializedName("conversation_id") val conversationId: String? = null, + @SerializedName("read_path") val readPath: String? = null, + @SerializedName("write_path") val writePath: String? = null, + @SerializedName("event_path") val eventsPath: String? = null, + @SerializedName("show_textbox") val showFreeText: Boolean? = null ) diff --git a/navi-chat/src/main/java/com/navi/chat/provider/ChatDataProvider.kt b/navi-chat/src/main/java/com/navi/chat/provider/ChatDataProvider.kt index 0267504466..0471b4485f 100644 --- a/navi-chat/src/main/java/com/navi/chat/provider/ChatDataProvider.kt +++ b/navi-chat/src/main/java/com/navi/chat/provider/ChatDataProvider.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.chat.provider import com.google.firebase.Timestamp @@ -12,5 +13,6 @@ import com.navi.naviwidgets.models.NaviChatWidget interface ChatDataProvider { fun initiate() fun listenToLiveMessages(senderName: String, latestMessageTimeStamp: Timestamp?) + fun listenToTypingStatus() fun writeMessage(naviChatWidget: NaviChatWidget) -} \ No newline at end of file +} diff --git a/navi-chat/src/main/java/com/navi/chat/provider/MessageOperation.kt b/navi-chat/src/main/java/com/navi/chat/provider/MessageOperation.kt index 2bd7bf56f2..0291025677 100644 --- a/navi-chat/src/main/java/com/navi/chat/provider/MessageOperation.kt +++ b/navi-chat/src/main/java/com/navi/chat/provider/MessageOperation.kt @@ -1,18 +1,21 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.chat.provider import com.navi.naviwidgets.models.NaviChatWidget import com.navi.naviwidgets.models.response.NaviChatControllerWidget import com.navi.naviwidgets.models.response.NaviChatCsatRatingWidget +import com.navi.naviwidgets.models.response.NaviChatTypingStatusWidget interface MessageOperation { fun addNewMessage(widgetModel: NaviChatWidget) fun showFeedbackFragment(naviChatCsatRatingWidget: NaviChatCsatRatingWidget) fun processControllerWidget(naviChatControllerWidget: NaviChatControllerWidget) fun updateTimestamp(widgetModel: NaviChatWidget) -} \ No newline at end of file + fun updateTypingStatus(naviChatTypingStatusWidget: NaviChatTypingStatusWidget) +} diff --git a/navi-chat/src/main/java/com/navi/chat/provider/firestore/FireStoreDataProvider.kt b/navi-chat/src/main/java/com/navi/chat/provider/firestore/FireStoreDataProvider.kt index 09499ca589..70a7cba5b0 100644 --- a/navi-chat/src/main/java/com/navi/chat/provider/firestore/FireStoreDataProvider.kt +++ b/navi-chat/src/main/java/com/navi/chat/provider/firestore/FireStoreDataProvider.kt @@ -11,6 +11,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent import com.google.firebase.Timestamp +import com.navi.base.utils.isNotNullAndNotEmpty import com.navi.chat.data.firestore.ChatFireStoreDatabase import com.navi.chat.di.scopes.NaviChatScope import com.navi.chat.models.FireStoreDataProviderModel @@ -57,6 +58,17 @@ constructor( } } + override fun listenToTypingStatus() { + if (::chatFireStoreDatabase.isInitialized) { + if (fireStoreDataProviderModel.eventsPath.isNotNullAndNotEmpty()) { + chatFireStoreDatabase.listenToFireStoreListenerForMessageStatus( + path = fireStoreDataProviderModel.eventsPath, + messageOperation = messageOperation + ) + } + } + } + override fun writeMessage(naviChatWidget: NaviChatWidget) { if (::chatFireStoreDatabase.isInitialized) { chatFireStoreDatabase.writeToFireStore( diff --git a/navi-chat/src/main/java/com/navi/chat/ui/fragments/NaviChatFragment.kt b/navi-chat/src/main/java/com/navi/chat/ui/fragments/NaviChatFragment.kt index 3ea9c264fc..997dbaede5 100644 --- a/navi-chat/src/main/java/com/navi/chat/ui/fragments/NaviChatFragment.kt +++ b/navi-chat/src/main/java/com/navi/chat/ui/fragments/NaviChatFragment.kt @@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator +import com.google.firebase.Timestamp import com.navi.analytics.utils.NaviTrackEvent import com.navi.base.model.CtaData import com.navi.base.model.NaviClickAction @@ -72,12 +73,12 @@ import com.navi.naviwidgets.utils.* import com.navi.naviwidgets.viewholder.NaviChatViewHolderFactoryImpl import dagger.hilt.android.EntryPointAccessors import java.io.File +import java.util.* import javax.inject.Inject import kotlinx.android.synthetic.main.fragment_common_navi_chat.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import timber.log.Timber @@ -107,7 +108,13 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T @Inject lateinit var fileHelper: FileHelper - private var handler = Handler(Looper.getMainLooper()) + private var fireStoreListenerHandler = Handler(Looper.getMainLooper()) + + private var typingStatusHandler = Handler(Looper.getMainLooper()) + + private var botTypingStatusHandler = Handler(Looper.getMainLooper()) + + private val botMessageList = ArrayList() private val fileSizes = HashMap() @@ -163,14 +170,14 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T wasFireStoreListenerRemoved = false Timber.d("${NaviChatFragment::class.simpleName}: On resume() listening to messages") } - handler.removeCallbacksAndMessages(null) + fireStoreListenerHandler.removeCallbacksAndMessages(null) } override fun onPause() { super.onPause() isAppInBackground = true - handler.postDelayed( + fireStoreListenerHandler.postDelayed( { if (isAppInBackground) { fireStoreDataProvider.removeFirestoreListener() @@ -184,7 +191,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T override fun onStop() { super.onStop() isAppInBackground = true - handler.postDelayed( + fireStoreListenerHandler.postDelayed( { if (isAppInBackground) { fireStoreDataProvider.removeFirestoreListener() @@ -354,7 +361,8 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T FireStoreDataProviderModel( chatProviderName = NaviChatSystemDataHelper.providerName().orEmpty(), readPath = naviChatInitiateResponse.readPath.orEmpty(), - writePath = naviChatInitiateResponse.writePath.orEmpty() + writePath = naviChatInitiateResponse.writePath.orEmpty(), + eventsPath = naviChatInitiateResponse.eventsPath.orEmpty() ) ) PreferenceManager.setStringPreference( @@ -557,6 +565,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T senderName = naviChatSystemLocalData?.currentUserName ?: EMPTY, latestMessageTimeStamp = naviChatViewModel.latestMessageTimeStamp ) + chatDataProvider.listenToTypingStatus() } } @@ -750,6 +759,62 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T rvChat.layoutManager?.onRestoreInstanceState(recyclerViewState) } + override fun updateTypingStatus(naviChatTypingStatusWidget: NaviChatTypingStatusWidget) { + if (naviChatTypingStatusWidget.typing == true) { + if (isValidTimeStamp(naviChatTypingStatusWidget.updatedAt)) { + showHideTypingStatus(naviChatTypingStatusWidget.typing ?: false) + } + } else { + showHideTypingStatus(naviChatTypingStatusWidget.typing ?: false) + } + } + + private fun isValidTimeStamp(updatedAt: Timestamp?): Boolean { + updatedAt?.let { + val milliseconds = updatedAt.seconds * 1000 + updatedAt.nanoseconds / 1000000 + if (System.currentTimeMillis() - milliseconds <= DELAY_TO_HIDE_TYPING) { + return true + } + } + return false + } + + private fun showHideTypingStatus(showTypingStatus: Boolean) { + if (showTypingStatus) { + if ( + chatRVAdapter.list.isEmpty() || chatRVAdapter.list[0] !is NaviChatTypingStatusWidget + ) { + chatRVAdapter.insertNewItemAtIndex( + 0, + NaviChatTypingStatusWidget(hint = TYPING_CUES_HINT) + ) + scrollChatToLatestMessageReceived() + } + typingStatusHandler.removeCallbacksAndMessages(null) + typingStatusHandler.postDelayed( + { + if ( + chatRVAdapter.list.isNotEmpty() && + chatRVAdapter.list[0] is NaviChatTypingStatusWidget + ) { + chatRVAdapter.removeItemAtIndex(0) + scrollChatToLatestMessageReceived() + } + }, + DELAY_TO_HIDE_TYPING + ) + } else { + typingStatusHandler.removeCallbacksAndMessages(null) + if ( + chatRVAdapter.list.isNotEmpty() && + chatRVAdapter.list[0] is NaviChatTypingStatusWidget + ) { + chatRVAdapter.removeItemAtIndex(0) + scrollChatToLatestMessageReceived() + } + } + } + override fun widgetStateChanged( position: Int?, data: Pair?, @@ -780,7 +845,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T linearLayoutManager.scrollToPosition(position) } - override fun addNewMessage(widgetModel: NaviChatWidget) { + private fun hideActionItemListIfNotReminder(widgetModel: NaviChatWidget) { if ( widgetModel.widgetNameForBaseAdapter == NaviChatConversationStatusWidget.WIDGET_NAME && chatRVAdapter.list.isNotEmpty() @@ -792,6 +857,11 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T hideChatActionItemList() } } + } + + override fun addNewMessage(widgetModel: NaviChatWidget) { + hideActionItemListIfNotReminder(widgetModel) + if ( widgetModel.widgetNameForBaseAdapter == NaviChatFileAttachmentWidget.WIDGET_NAME && widgetModel is NaviChatFileAttachmentWidget @@ -799,12 +869,61 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T if (widgetModel.widgetData?.state.isNullOrEmpty()) widgetModel.widgetData?.state = DOWNLOAD_STATE } - chatRVAdapter.insertNewItemAtIndex(0, widgetModel) - Timber.d("Adding new item ${widgetModel.rt_created_at}, setting latest timestamp") + + if (widgetModel.senderType.equals(BOT, true)) { + if ( + widgetModel.widgetNameForBaseAdapter != NaviChatConversationStatusWidget.WIDGET_NAME + ) { + if ( + chatRVAdapter.list.isNotEmpty() && + chatRVAdapter.list[0] is NaviChatTypingStatusWidget + ) { + botMessageList.add(widgetModel) + } else { + showHideTypingStatus(true) + botMessageList.add(widgetModel) + typingStatusHandler.postDelayed( + { + addBotMessageListToAdapterAndHideTypingStatus() + naviChatViewModel.setLatestMessageLatestTimeStamp( + widgetModel.rt_created_at + ) + }, + DELAY_TO_HIDE_TYPING_FOR_BOT + ) + } + } else { + typingStatusHandler.removeCallbacksAndMessages(null) + addBotMessageListToAdapterAndHideTypingStatus() + insertItemAtIndexAndSetTimeStamp(0, widgetModel) + } + } else { + if ( + chatRVAdapter.list.isNotEmpty() && + chatRVAdapter.list[0] is NaviChatTypingStatusWidget + ) { + insertItemAtIndexAndSetTimeStamp(1, widgetModel) + } else { + insertItemAtIndexAndSetTimeStamp(0, widgetModel) + } + } + } + + private fun insertItemAtIndexAndSetTimeStamp(index: Int, widgetModel: NaviChatWidget) { + chatRVAdapter.insertNewItemAtIndex(index, widgetModel) scrollChatToLatestMessageReceived() naviChatViewModel.setLatestMessageLatestTimeStamp(widgetModel.rt_created_at) } + private fun addBotMessageListToAdapterAndHideTypingStatus() { + showHideTypingStatus(false) + for (message in botMessageList) { + chatRVAdapter.insertNewItemAtIndex(0, message) + scrollChatToLatestMessageReceived() + } + botMessageList.clear() + } + override fun updateTimestamp(widgetModel: NaviChatWidget) { if ( widgetModel.widgetNameForBaseAdapter == NaviChatFileAttachmentWidget.WIDGET_NAME && @@ -878,6 +997,9 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T override fun onDestroyView() { super.onDestroyView() + fireStoreListenerHandler.removeCallbacksAndMessages(null) + botTypingStatusHandler.removeCallbacksAndMessages(null) + typingStatusHandler.removeCallbacksAndMessages(null) fileUploadManager.cancelUploads() } @@ -887,5 +1009,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T const val TAG = "NaviChatFragment" private const val DELAY_TO_SCROLL = 200L private const val RECYCLER_VIEW_BOOT_DELAY = 3000L + private const val DELAY_TO_HIDE_TYPING = 10000L + private const val DELAY_TO_HIDE_TYPING_FOR_BOT = 3000L } } diff --git a/navi-chat/src/main/java/com/navi/chat/utils/ChatPLScreens.kt b/navi-chat/src/main/java/com/navi/chat/utils/ChatPLScreens.kt index 2b7dff4baf..e2d37531e0 100644 --- a/navi-chat/src/main/java/com/navi/chat/utils/ChatPLScreens.kt +++ b/navi-chat/src/main/java/com/navi/chat/utils/ChatPLScreens.kt @@ -15,5 +15,6 @@ enum class ChatPLScreens { PL_BANK_DETAIL_AUTO_DEBIT_SCREEN, PL_LOAN_AGREEMENT_SCREEN, PL_CARD_SCREEN, - PROFILE_CHAT_SCREEN + PROFILE_CHAT_SCREEN, + PL_DELAYED_DISBURSEMENT_SCREEN } \ No newline at end of file diff --git a/navi-chat/src/main/java/com/navi/chat/utils/Constants.kt b/navi-chat/src/main/java/com/navi/chat/utils/Constants.kt index 786ff0d6a2..adb006710f 100644 --- a/navi-chat/src/main/java/com/navi/chat/utils/Constants.kt +++ b/navi-chat/src/main/java/com/navi/chat/utils/Constants.kt @@ -16,10 +16,13 @@ const val PAGE_SIZE = 10 /* Event names */ const val CSAT_SURVEY_LAUNCHED = "chat_CSAT_survey_launched" -const val SUBMIT_BUTTON_CLICKED = "chat_CSAT_submit_button_clicked" -const val SKIP_BUTTON_CLICKED = "chat_CSAT_skip_button_clicked" const val CHAT_BOT_LOADED = "chat_bot_loaded" const val CHAT_TOUCH_POINT_CLICKED = "chat_touch_point_clicked" +const val CHAT_PN_RECEIVED = "chat_pn_received" +const val CHAT_PN_OPENED = "chat_pn_opened" +const val SCREEN_NAME = "screen_name" +const val CHAT_SCREEN = "chat_screen" +const val HOME_SCREEN = "home_screen" /* Event param constants */ const val TRACKING_UUID = "uuid" @@ -35,3 +38,7 @@ const val FILE_TYPE_PARAM = "fileType" const val CONVERSATION_ID_PARAM = "conversationId" const val FILE_UUID_PARAM = "fileUuid" const val NAVI_CHAT_SYSTEM_REMOTE_DATA = "naviChatSystemRemoteData" +const val TYPING_CUES_PATH_AGENT = "agent" +const val TYPING_CUES_HINT = "Typing..." +const val BOT = "BOT" + diff --git a/navi-common/build.gradle b/navi-common/build.gradle index 367df0ab2f..0eef3c717c 100644 --- a/navi-common/build.gradle +++ b/navi-common/build.gradle @@ -61,8 +61,8 @@ dependencies { implementation 'com.google.firebase:firebase-analytics' debugApi 'com.github.chuckerteam.chucker:library:3.5.2' releaseApi 'com.github.chuckerteam.chucker:library-no-op:3.5.2' - implementation "com.squareup.retrofit2:retrofit:2.9.0" - implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + api "com.squareup.retrofit2:retrofit:2.9.0" + api 'com.squareup.retrofit2:converter-gson:2.9.0' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' @@ -76,9 +76,6 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.10.0' kapt 'com.github.bumptech.glide:compiler:4.10.0' - // Gson - implementation 'com.squareup.retrofit2:converter-gson:2.9.0' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2' implementation playCore.implementation @@ -131,7 +128,7 @@ dependencies { api "com.google.android.gms:play-services-location:17.0.0" //Digio: for adhaar verification - api project(":digio-kyc-3.1.5") + api project(":digio-kyc-3.1.7") //Digio e-nach api project(":digio-esign-v2.8.9") diff --git a/navi-common/src/main/java/com/navi/common/CommonLibManager.kt b/navi-common/src/main/java/com/navi/common/CommonLibManager.kt index 5d56c5fc13..791516a281 100644 --- a/navi-common/src/main/java/com/navi/common/CommonLibManager.kt +++ b/navi-common/src/main/java/com/navi/common/CommonLibManager.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -8,13 +8,13 @@ package com.navi.common import android.app.Application +import com.navi.base.sharedpref.PreferenceManager import com.navi.common.deeplink.DeepLinkManager import com.navi.common.deeplink.listener.DeepLinkListener import com.navi.common.model.NetworkInfo import com.navi.common.network.ApiConstants import com.navi.common.network.retrofit.CommonHttpClient import com.navi.common.network.retrofit.RetrofitService -import com.navi.base.sharedpref.PreferenceManager import okhttp3.OkHttpClient import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @@ -33,12 +33,13 @@ object CommonLibManager { PreferenceManager.init(application) DeepLinkManager.init(listener) - val networkInfo = NetworkInfo( - appVersionName = appVersionName, - appVersionCode = appVersionCode, - moduleName = null, - timeoutInSec = ApiConstants.API_CONNECT_TIMEOUT_VALUE - ) + val networkInfo = + NetworkInfo( + appVersionName = appVersionName, + appVersionCode = appVersionCode, + moduleName = null, + timeoutInSec = ApiConstants.API_CONNECT_TIMEOUT_VALUE + ) commonRetrofitService = createRetrofitService( @@ -51,11 +52,12 @@ object CommonLibManager { baseUrl: String, okttpClientBuilder: OkHttpClient.Builder ): RetrofitService { - val retrofitClient = Retrofit.Builder() - .baseUrl(baseUrl) - .addConverterFactory(GsonConverterFactory.create()) - .client(okttpClientBuilder.build()) - .build() + val retrofitClient = + Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create()) + .client(okttpClientBuilder.build()) + .build() return retrofitClient.create(RetrofitService::class.java) } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/ResponseState.kt b/navi-common/src/main/java/com/navi/common/ResponseState.kt new file mode 100644 index 0000000000..ed562650d6 --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/ResponseState.kt @@ -0,0 +1,25 @@ +package com.navi.common + +sealed interface ResponseState { + object Idle : ResponseState + object Loading : ResponseState + data class Success(val value: T) : ResponseState + data class Failure(val errorMessage: String) : ResponseState + + operator fun invoke() = (this as? Success)?.value +} + +inline fun ResponseState.onSuccess(block: (T) -> Unit) = also { + (it as? ResponseState.Success)?.value?.let(block) +} + +inline fun ResponseState.onFailure(block: (String) -> Unit) = also { + (it as? ResponseState.Failure)?.errorMessage?.let(block) +} + +inline fun ResponseState.map(block: (T) -> R): ResponseState = when (this) { + is ResponseState.Success -> ResponseState.Success(block(value)) + is ResponseState.Failure -> ResponseState.Failure(errorMessage) + ResponseState.Idle -> ResponseState.Idle + ResponseState.Loading -> ResponseState.Loading +} \ No newline at end of file diff --git a/navi-common/src/main/java/com/navi/common/awsupload/AWSFileType.kt b/navi-common/src/main/java/com/navi/common/awsupload/AWSFileType.kt index 0dd8ad1fb0..8cbbfa304c 100644 --- a/navi-common/src/main/java/com/navi/common/awsupload/AWSFileType.kt +++ b/navi-common/src/main/java/com/navi/common/awsupload/AWSFileType.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.awsupload enum class AWSFileType(val value: String) { @@ -11,7 +18,6 @@ enum class AWSFileType(val value: String) { BMP("BMP"), UNKNOWN("UNKNOWN"); - fun getValueOf(value: String): AWSFileType { return try { valueOf(value) @@ -19,4 +25,4 @@ enum class AWSFileType(val value: String) { UNKNOWN } } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/awsupload/helper/AWSUploadHelper.kt b/navi-common/src/main/java/com/navi/common/awsupload/helper/AWSUploadHelper.kt index 2daccadbcd..3bf6aebda2 100644 --- a/navi-common/src/main/java/com/navi/common/awsupload/helper/AWSUploadHelper.kt +++ b/navi-common/src/main/java/com/navi/common/awsupload/helper/AWSUploadHelper.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.awsupload.helper import com.navi.common.awsupload.AWSFileType @@ -11,7 +18,8 @@ object AWSUploadHelper { const val PNG_CONTENT_TYPE = "image/png" const val MP4_CONTENT_TYPE = "video/mp4" const val PDF_CONTENT_TYPE = "application/pdf" - const val DOCX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + const val DOCX_CONTENT_TYPE = + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" const val DOC_CONTENT_TYPE = "application/msword" fun getContentTypeForFileType(awsFileType: AWSFileType): String { @@ -55,4 +63,4 @@ object AWSUploadHelper { partMap.put("Content-Type", contentType) return partMap } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/customview/ActionButtonV2View.kt b/navi-common/src/main/java/com/navi/common/customview/ActionButtonV2View.kt index 32a581668f..6db995ed75 100644 --- a/navi-common/src/main/java/com/navi/common/customview/ActionButtonV2View.kt +++ b/navi-common/src/main/java/com/navi/common/customview/ActionButtonV2View.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.customview import android.content.Context @@ -12,11 +19,10 @@ import com.navi.common.R import com.navi.common.databinding.ActionButtonV2ViewBinding import com.navi.design.utils.getNaviDrawable -class ActionButtonV2View @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : LinearLayout(context, attrs, defStyleAttr) { +class ActionButtonV2View +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + LinearLayout(context, attrs, defStyleAttr) { private lateinit var binding: ActionButtonV2ViewBinding init { @@ -29,22 +35,18 @@ class ActionButtonV2View @JvmOverloads constructor( } fun setProperties( - title : String? = null, + title: String? = null, titleColor: Int? = R.color.white, - backgroundColor : Int? = R.color.outrageous_orange + backgroundColor: Int? = R.color.outrageous_orange ) { binding.actionTv.text = title - titleColor?.let { - binding.actionTv.setTextColor(ContextCompat.getColor(context, it)) - } + titleColor?.let { binding.actionTv.setTextColor(ContextCompat.getColor(context, it)) } backgroundColor?.let { - binding.actionTv.background = getNaviDrawable( - backgroundColor = ResourcesCompat.getColor( - resources, - backgroundColor, null - ), - cornerRadius = resources.getDimension(R.dimen.layout_dp_100).toInt() - ) + binding.actionTv.background = + getNaviDrawable( + backgroundColor = ResourcesCompat.getColor(resources, backgroundColor, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_100).toInt() + ) } } @@ -58,12 +60,10 @@ class ActionButtonV2View @JvmOverloads constructor( } fun setABVBackgroundColor(bgColor: Int? = null) { - bgColor?.apply { - binding.actionTv.setBackgroundResource(this) - } + bgColor?.apply { binding.actionTv.setBackgroundResource(this) } } fun setCtaTitle(ctaData: CtaData) { ctaData.title?.let { setProperties(title = it) } } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/customview/BoxInputGroup.kt b/navi-common/src/main/java/com/navi/common/customview/BoxInputGroup.kt index 43a4ef6227..8a7191d7fe 100644 --- a/navi-common/src/main/java/com/navi/common/customview/BoxInputGroup.kt +++ b/navi-common/src/main/java/com/navi/common/customview/BoxInputGroup.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -24,7 +24,9 @@ import com.navi.common.utils.* import kotlinx.android.synthetic.main.otp_box_layout_comm.view.* class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : - LinearLayout(context, attributeSet), TextWatcher, View.OnFocusChangeListener, + LinearLayout(context, attributeSet), + TextWatcher, + View.OnFocusChangeListener, View.OnKeyListener { private val binding: BoxInputGroupLayoutCommBinding @@ -52,9 +54,7 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : } private fun initListeners(onClickListener: OnClickListener? = null) { - editTextBoxes.forEach { - addListeners(it) - } + editTextBoxes.forEach { addListeners(it) } binding.otpView.setOnClickListener { onClickListener?.onClick(it) val firstEmptyEditText = editTextBoxes.find { it.text.toString().isEmpty() } @@ -71,8 +71,9 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : private fun inflateItems(size: Int) { for (position in 1..size) { - val otpView = LayoutInflater.from(context) - .inflate(R.layout.otp_box_layout_comm, binding.otpLayout, false) + val otpView = + LayoutInflater.from(context) + .inflate(R.layout.otp_box_layout_comm, binding.otpLayout, false) val layoutParams = otpView.layoutParams as LayoutParams layoutParams.setMargins( 0, @@ -94,9 +95,7 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : fun getText(): String { var otp = EMPTY - editTextBoxes.forEach { - otp = otp.plus(it.text.toString()) - } + editTextBoxes.forEach { otp = otp.plus(it.text.toString()) } return otp } @@ -120,9 +119,7 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : } fun clear() { - editTextBoxes.forEach { - it.text.clear() - } + editTextBoxes.forEach { it.text.clear() } editTextBoxes.getOrNull(0)?.requestFocus() } @@ -131,8 +128,9 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : getCurrentFocusedItemIndex()?.let { focusedItemIndex -> if (editable.toString().isNotEmpty() && focusedItemIndex + 1 < editTextBoxes.count()) { editTextBoxes[focusedItemIndex + 1].requestFocus() - } else if (focusedItemIndex > 0 && editTextBoxes[focusedItemIndex - 1].text.toString() - .isEmpty() + } else if ( + focusedItemIndex > 0 && + editTextBoxes[focusedItemIndex - 1].text.toString().isEmpty() ) { editTextBoxes[focusedItemIndex - 1].requestFocus() } else return @@ -167,19 +165,21 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : fun setBoxBg(isError: Boolean) { if (isError) { editTextBoxes.forEach { - it.background = ResourcesCompat.getDrawable( - context.resources, - R.drawable.error_rectangle_bg, - null - ) + it.background = + ResourcesCompat.getDrawable( + context.resources, + R.drawable.error_rectangle_bg, + null + ) } } else { editTextBoxes.forEach { - it.background = ResourcesCompat.getDrawable( - context.resources, - R.drawable.default_rectangle_bg, - null - ) + it.background = + ResourcesCompat.getDrawable( + context.resources, + R.drawable.default_rectangle_bg, + null + ) } } } @@ -202,4 +202,4 @@ class BoxInputGroup(context: Context, attributeSet: AttributeSet? = null) : const val OTP_LENGTH_4 = 4 const val OTP_LENGTH_6 = 6 } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/deeplink/util/DeeplinkConstants.kt b/navi-common/src/main/java/com/navi/common/deeplink/util/DeeplinkConstants.kt index c22a20e4d1..2ec8c95df3 100644 --- a/navi-common/src/main/java/com/navi/common/deeplink/util/DeeplinkConstants.kt +++ b/navi-common/src/main/java/com/navi/common/deeplink/util/DeeplinkConstants.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -14,4 +14,4 @@ object DeeplinkConstants { const val INSURANCE = "Insurance" const val SPLASH = "SPLASH" const val USER_DETAIL = "userdetail" -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/downloader/DownloadUtil.kt b/navi-common/src/main/java/com/navi/common/downloader/DownloadUtil.kt index 568f62b15f..54c3ccc56d 100644 --- a/navi-common/src/main/java/com/navi/common/downloader/DownloadUtil.kt +++ b/navi-common/src/main/java/com/navi/common/downloader/DownloadUtil.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.downloader import android.app.DownloadManager @@ -38,8 +45,10 @@ object DownloadUtil { destinationPath: URI, notificationVisibility: Int ) { - request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE) + request.setAllowedNetworkTypes( + DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE + ) request.setNotificationVisibility(notificationVisibility) request.setDestinationUri(destinationPath.toString().toUri()) } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/extensions/Ext.kt b/navi-common/src/main/java/com/navi/common/extensions/Ext.kt index 712bdc2ca5..97c815eaa4 100644 --- a/navi-common/src/main/java/com/navi/common/extensions/Ext.kt +++ b/navi-common/src/main/java/com/navi/common/extensions/Ext.kt @@ -18,7 +18,6 @@ import androidx.appcompat.content.res.AppCompatResources import com.navi.common.R import com.navi.common.listeners.OnPopupMenuClickListener - /** * reduces the size of the bitmap * @param maxSize, default size is assumed to be 500 @@ -47,30 +46,18 @@ fun showPopupMenu( width: Int? = null, ) { val popupMenu = ListPopupWindow(context) - width?.let { - popupMenu.width = it - } - popupMenu.setAdapter( - ArrayAdapter( - context, - R.layout.spinner_dropdown, - array - ) - ) + width?.let { popupMenu.width = it } + popupMenu.setAdapter(ArrayAdapter(context, R.layout.spinner_dropdown, array)) popupMenu.anchorView = view popupMenu.verticalOffset = -20 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { popupMenu.setBackgroundDrawable( - AppCompatResources.getDrawable( - context, - R.drawable.popup_solid_curve - ) + AppCompatResources.getDrawable(context, R.drawable.popup_solid_curve) ) } popupMenu.isModal = true - popupMenu.setOnDismissListener { - } + popupMenu.setOnDismissListener {} popupMenu.setOnItemClickListener { _, _, position, _ -> listener.onSelect(array[position]) @@ -85,4 +72,4 @@ fun Any?.isNull(): Boolean = this == null fun Any?.isNotNull(): Boolean = !this.isNull() -fun String?.isNotNullAndNotEmpty(): Boolean = !this.isNullOrEmpty() \ No newline at end of file +fun String?.isNotNullAndNotEmpty(): Boolean = !this.isNullOrEmpty() diff --git a/navi-common/src/main/java/com/navi/common/image/GlideUtil.kt b/navi-common/src/main/java/com/navi/common/image/GlideUtil.kt index 94339d6e3c..6ec1ead82c 100644 --- a/navi-common/src/main/java/com/navi/common/image/GlideUtil.kt +++ b/navi-common/src/main/java/com/navi/common/image/GlideUtil.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -16,18 +16,16 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.navi.common.R /** - * Url string is optional as placeholder image will be shown by default in case url is not present or is invalid. - **/ + * Url string is optional as placeholder image will be shown by default in case url is not present + * or is invalid. + */ fun loadUrlIntoImageView( context: Context, url: String?, view: ImageView, isCacheNeeded: Boolean = true, - imagePlaceholder: Drawable? = ResourcesCompat.getDrawable( - context.resources, - R.drawable.widget_image_placeholder, - null - ) + imagePlaceholder: Drawable? = + ResourcesCompat.getDrawable(context.resources, R.drawable.widget_image_placeholder, null) ) { try { if (isCacheNeeded) @@ -36,9 +34,6 @@ fun loadUrlIntoImageView( .placeholder(imagePlaceholder) .diskCacheStrategy(DiskCacheStrategy.DATA) .into(view) - else - Glide.with(context).load(url).into(view) - } catch (e: Exception) { - - } -} \ No newline at end of file + else Glide.with(context).load(url).into(view) + } catch (e: Exception) {} +} diff --git a/navi-common/src/main/java/com/navi/common/listeners/ApiCallListener.kt b/navi-common/src/main/java/com/navi/common/listeners/ApiCallListener.kt index db7a669c37..c7d9d9c4ed 100644 --- a/navi-common/src/main/java/com/navi/common/listeners/ApiCallListener.kt +++ b/navi-common/src/main/java/com/navi/common/listeners/ApiCallListener.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -38,6 +38,5 @@ interface ApiCallListener { screenName: String?, error: GenericErrorResponse?, errorMessage: ErrorMessage? - ) { - } -} \ No newline at end of file + ) {} +} diff --git a/navi-common/src/main/java/com/navi/common/listeners/FragmentInterchangeListener.kt b/navi-common/src/main/java/com/navi/common/listeners/FragmentInterchangeListener.kt index 66bbf799c9..c0c8ac64b3 100644 --- a/navi-common/src/main/java/com/navi/common/listeners/FragmentInterchangeListener.kt +++ b/navi-common/src/main/java/com/navi/common/listeners/FragmentInterchangeListener.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -14,4 +14,4 @@ interface FragmentInterchangeListener { fun navigateToNextScreen(currentScreenTag: String, bundle: Bundle) fun navigateToNextScreen(actionData: ActionData?, bundle: Bundle = Bundle()) {} fun onActivityCompleted() {} -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/listeners/HeaderInteractionListener.kt b/navi-common/src/main/java/com/navi/common/listeners/HeaderInteractionListener.kt index a229fc2c33..7e25615aec 100644 --- a/navi-common/src/main/java/com/navi/common/listeners/HeaderInteractionListener.kt +++ b/navi-common/src/main/java/com/navi/common/listeners/HeaderInteractionListener.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -23,8 +23,7 @@ interface HeaderInteractionListener { @StyleRes styleResId: Int? = null, titleCentric: Boolean = false, rotation: Float = 0F - ) { - } + ) {} fun hideHeader() {} fun hideBackButton() {} @@ -35,4 +34,4 @@ interface HeaderInteractionListener { fun setProperties(header: Header?) {} fun onClick(actionData: ActionData?) {} fun onHelpClick(helpBottomSheetData: HelpBottomSheetData?) {} -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/managers/PermissionsManager.kt b/navi-common/src/main/java/com/navi/common/managers/PermissionsManager.kt index 8cf0026f08..a16ad0885c 100644 --- a/navi-common/src/main/java/com/navi/common/managers/PermissionsManager.kt +++ b/navi-common/src/main/java/com/navi/common/managers/PermissionsManager.kt @@ -19,23 +19,23 @@ class PermissionsManager(private val activity: Activity) { fun hasPermissions(permissions: Array = requiredPermissions): Boolean = permissions.all { permission -> ContextCompat.checkSelfPermission(activity, permission) == - PackageManager.PERMISSION_GRANTED + PackageManager.PERMISSION_GRANTED } fun hasPermissionsAny(permissions: Array = requiredPermissions): Boolean = permissions.any { permission -> ContextCompat.checkSelfPermission(activity, permission) == - PackageManager.PERMISSION_GRANTED + PackageManager.PERMISSION_GRANTED } fun hasLocationPermissionAny(): Boolean { return arrayOf( - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION - ) + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ) .any { permission -> ContextCompat.checkSelfPermission(activity, permission) == - PackageManager.PERMISSION_GRANTED + PackageManager.PERMISSION_GRANTED } } diff --git a/navi-common/src/main/java/com/navi/common/model/GenericMenuItem.kt b/navi-common/src/main/java/com/navi/common/model/GenericMenuItem.kt index 158324d8d1..c8c5284e6a 100644 --- a/navi-common/src/main/java/com/navi/common/model/GenericMenuItem.kt +++ b/navi-common/src/main/java/com/navi/common/model/GenericMenuItem.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.model import android.os.Parcelable @@ -8,22 +15,13 @@ import kotlinx.android.parcel.Parcelize @Parcelize data class GenericMenuItem( - @SerializedName("title") - val title: String? = null, - @SerializedName("imageDetail") - val imageDetail: ImageDetail? = null, - @SerializedName("cta") - var cta: ActionData? = null, - @SerializedName("currentPage") - var currentPage: Boolean? = false, - @SerializedName("iconCode") - val iconCode: String? = null, - @SerializedName("enabled") - val enabled: Boolean? = null, - @SerializedName("subtitle") - val subtitle: String? = null, - @SerializedName("itemType") - val itemType: String? = null, - @SerializedName("metaData") - val metaData: HashMap? = null + @SerializedName("title") val title: String? = null, + @SerializedName("imageDetail") val imageDetail: ImageDetail? = null, + @SerializedName("cta") var cta: ActionData? = null, + @SerializedName("currentPage") var currentPage: Boolean? = false, + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("enabled") val enabled: Boolean? = null, + @SerializedName("subtitle") val subtitle: String? = null, + @SerializedName("itemType") val itemType: String? = null, + @SerializedName("metaData") val metaData: HashMap? = null ) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/Header.kt b/navi-common/src/main/java/com/navi/common/model/Header.kt index 99140098e1..819305987a 100644 --- a/navi-common/src/main/java/com/navi/common/model/Header.kt +++ b/navi-common/src/main/java/com/navi/common/model/Header.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.model import android.os.Parcelable @@ -22,4 +29,4 @@ data class HelpData( @SerializedName("title") var title: TextWithStyle? = null, @SerializedName("cta") var cta: ActionData? = null, @SerializedName("helpBottomSheet") var helpBottomSheet: HelpBottomSheetData? = null, -): Parcelable \ No newline at end of file +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/HelpBottomSheetData.kt b/navi-common/src/main/java/com/navi/common/model/HelpBottomSheetData.kt index 3b34e2e8db..55aef96a23 100644 --- a/navi-common/src/main/java/com/navi/common/model/HelpBottomSheetData.kt +++ b/navi-common/src/main/java/com/navi/common/model/HelpBottomSheetData.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.model import android.os.Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/KycStatus.kt b/navi-common/src/main/java/com/navi/common/model/KycStatus.kt new file mode 100644 index 0000000000..40d5a38596 --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/KycStatus.kt @@ -0,0 +1,33 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.navi.navi_vkyc.models.Footer +import com.navi.navi_vkyc.models.Header +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class KycStatus( + @SerializedName("kyc") val kyc: String? = null, + @SerializedName("verificationType") val verificationType: String? = null, + @SerializedName("customerCarePhoneNum") val customerCareNumber: String? = null, + @SerializedName("completeAddress") val completeAddress: String? = null, + @SerializedName("addressProofType") val addressProofType: String? = null, + @SerializedName("addressProofUploadTitle") val addressProofUploadTitle: String? = null, + @SerializedName("isAddressProofEditable") val isAddressProofEditable: Boolean? = null, + @SerializedName("customerReferenceId") val customerReferenceId: String? = null +) : Parcelable + +@Parcelize +data class KycInReviewResponse( + @SerializedName("header") val header: Header? = null, + @SerializedName("content") val content: KycStatus? = null, + @SerializedName("footer") val footer: Footer? = null +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/LabelData.kt b/navi-common/src/main/java/com/navi/common/model/LabelData.kt index 819ff48b92..4d2962d44e 100644 --- a/navi-common/src/main/java/com/navi/common/model/LabelData.kt +++ b/navi-common/src/main/java/com/navi/common/model/LabelData.kt @@ -1,13 +1,17 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.model import com.google.gson.annotations.SerializedName import com.navi.design.textview.model.TextWithStyle data class LabelData( - @SerializedName("title") - val title: TextWithStyle? = null, - @SerializedName("borderColor") - val borderColor: String? = null, - @SerializedName("bgColor") - val bgColor: String? = null -) \ No newline at end of file + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("borderColor") val borderColor: String? = null, + @SerializedName("bgColor") val bgColor: String? = null +) diff --git a/navi-common/src/main/java/com/navi/common/model/ModuleNameV2.kt b/navi-common/src/main/java/com/navi/common/model/ModuleNameV2.kt index 84b640eb8a..39b8a48f58 100644 --- a/navi-common/src/main/java/com/navi/common/model/ModuleNameV2.kt +++ b/navi-common/src/main/java/com/navi/common/model/ModuleNameV2.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -8,8 +8,8 @@ package com.navi.common.model enum class ModuleNameV2 { - PL, //For Personal Loan Activities - HL, //For Home Loan Activities - AMC, //For AMC Activities - COMMON//For Common Activities -} \ No newline at end of file + PL, // For Personal Loan Activities + HL, // For Home Loan Activities + AMC, // For AMC Activities + COMMON // For Common Activities +} diff --git a/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt b/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt index 7c51661aec..916aaa0e49 100644 --- a/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt +++ b/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -10,14 +10,14 @@ package com.navi.common.model data class NetworkInfo( val appVersionName: String, val appVersionCode: String, - val moduleName: ModuleName?,//null for SuperApp APIs + val moduleName: ModuleName?, // null for SuperApp APIs val timeoutInSec: Long ) enum class ModuleName { - LE, //For lending API - GI, //For insurance API - AMC, //For AMC API + LE, // For lending API + GI, // For insurance API + AMC, // For AMC API CRM, // For chat API LITMUS, // For AB Experiment API GROOT // For deeplink diff --git a/navi-common/src/main/java/com/navi/common/model/ProviderType.kt b/navi-common/src/main/java/com/navi/common/model/ProviderType.kt index 5d9a44cf6c..f9cb4b8990 100644 --- a/navi-common/src/main/java/com/navi/common/model/ProviderType.kt +++ b/navi-common/src/main/java/com/navi/common/model/ProviderType.kt @@ -1,6 +1,7 @@ /* - * * - * * Copyright (c) 2020 . All rights reserved @Navi + * + * * Copyright © 2020-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -15,8 +16,7 @@ object ProviderType { const val DIGITAP = "DIGITAP" const val STUB_PROVIDER = "STUB_PROVIDER" - @StringDef(RAZORPAY, DIGIO, DIGITAP, STUB_PROVIDER) @Retention(AnnotationRetention.SOURCE) annotation class ProviderTypeDef -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/model/RedirectPageStatus.kt b/navi-common/src/main/java/com/navi/common/model/RedirectPageStatus.kt new file mode 100644 index 0000000000..938f5488c5 --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/RedirectPageStatus.kt @@ -0,0 +1,23 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class RedirectPageStatus( + @SerializedName("page") val page: String? = null, + @SerializedName("subPage") val subPage: String? = null, + @SerializedName("softReject") val softReject: Boolean? = null, + @SerializedName("rejectReason") val rejectReason: String? = null, + @SerializedName("pageStatus") val pageStatus: String? = null, + @SerializedName("subPageStatus") val subPageStatus: String? = null, + @SerializedName("ratingEnabled") val ratingEnabled: Boolean? = null +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/UploadDataAsyncResponse.kt b/navi-common/src/main/java/com/navi/common/model/UploadDataAsyncResponse.kt index 30872ed4c2..23b66578da 100644 --- a/navi-common/src/main/java/com/navi/common/model/UploadDataAsyncResponse.kt +++ b/navi-common/src/main/java/com/navi/common/model/UploadDataAsyncResponse.kt @@ -25,4 +25,4 @@ open class RequestConfig( @SerializedName("interval") val interval: Int? = null, @SerializedName("multiplyFactor") val multiplyFactor: Int? = null, @SerializedName("numOfRetries") val numOfRetries: Int? = null -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/com/naviapp/permission/models/PermissionTile.kt b/navi-common/src/main/java/com/navi/common/model/permission/PermissionTile.kt similarity index 69% rename from app/src/main/java/com/naviapp/permission/models/PermissionTile.kt rename to navi-common/src/main/java/com/navi/common/model/permission/PermissionTile.kt index 635fd15522..41ade67ea4 100644 --- a/app/src/main/java/com/naviapp/permission/models/PermissionTile.kt +++ b/navi-common/src/main/java/com/navi/common/model/permission/PermissionTile.kt @@ -5,17 +5,16 @@ * */ -package com.naviapp.permission.models +package com.navi.common.model.permission import android.graphics.drawable.Drawable -import com.naviapp.permission.adapters.PermissionAdapter.Companion.DEFAULT_PERMISSION_STATE data class PermissionTile( var icon: Drawable?, var title: String, var description: String, val qualifier: List? = null, - var permissionState: Int = DEFAULT_PERMISSION_STATE, + var permissionState: Int = 1, var iconCode: String? = null, var allowed: Boolean? = false, var statusVisibility: Boolean? = false diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/InfoBottomSheetConfig.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/InfoBottomSheetConfig.kt new file mode 100644 index 0000000000..076e0b03a3 --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/InfoBottomSheetConfig.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model.vkyc + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.common.model.StyledTextWithIconCode +import kotlinx.android.parcel.Parcelize + +@Parcelize +class InfoBottomSheetConfig( + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("title") val title: String? = null, + @SerializedName("styledDescription") val styledDescription: StyledTextWithIconCode? = null, + @SerializedName("cta") val cta: CtaData? = null +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/PermissionDetailsResponse.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/PermissionDetailsResponse.kt new file mode 100644 index 0000000000..a080a82352 --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/PermissionDetailsResponse.kt @@ -0,0 +1,43 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.common.model.vkyc.InfoBottomSheetConfig +import kotlinx.android.parcel.Parcelize + +data class PermissionDetailsResponse( + @SerializedName("header") val header: Header? = null, + @SerializedName("content") val content: PermissionDetailsContent? = null, + @SerializedName("footer") val footer: Footer? = null +) + +data class PermissionDetailsContent( + @SerializedName("dataSafetyBottomSheet") + val dataSafetyBottomSheet: InfoBottomSheetConfig? = null +) + +@Parcelize +data class Header( + @SerializedName("title") val title: String? = null, + @SerializedName("subtitle") val subtitle: String? = null, + @SerializedName("description") val description: String? = null, + @SerializedName("progress") val progress: Int? = null, + @SerializedName("leftIconCode") val leftIconCode: String? = null, + @SerializedName("infoCta") val infoCta: CtaData? = null, + @SerializedName("enableHelp") val enableHelp: Boolean? = null +) : Parcelable + +@Parcelize +data class Footer( + @SerializedName("backCta") val backCta: CtaData? = null, + @SerializedName("nextCta") val nextCta: CtaData? = null, + @SerializedName("progress") val progress: Int? = null +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/VkycCancelStatus.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycCancelStatus.kt new file mode 100644 index 0000000000..fa417e5fda --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycCancelStatus.kt @@ -0,0 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model.vkyc + +data class VkycCancelStatus(val updated: String) diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/VkycSettingsResponse.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycSettingsResponse.kt new file mode 100644 index 0000000000..680a01d41e --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycSettingsResponse.kt @@ -0,0 +1,24 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model.vkyc + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import kotlinx.android.parcel.Parcelize + +class VkycSettingsResponse { + @SerializedName("settings") val settings: VkycSettings? = null + @SerializedName("KycSourceReferenceId") val kycSourceReferenceId: String? = null +} + +@Parcelize +data class VkycSettings( + @SerializedName("userName") val userName: String? = null, + @SerializedName("authToken") val authToken: String? = null, + @SerializedName("referenceId") val referenceId: String? = null +) : Parcelable diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/VkycStatus.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycStatus.kt new file mode 100644 index 0000000000..d34f19d80c --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/VkycStatus.kt @@ -0,0 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model.vkyc + +data class VkycStatus(val status: String) diff --git a/navi-common/src/main/java/com/navi/common/model/vkyc/WaitingPageDetailsResponse.kt b/navi-common/src/main/java/com/navi/common/model/vkyc/WaitingPageDetailsResponse.kt new file mode 100644 index 0000000000..bcc7f1035c --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/model/vkyc/WaitingPageDetailsResponse.kt @@ -0,0 +1,13 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.model.vkyc + +import com.google.gson.annotations.SerializedName +import com.navi.navi_vkyc.models.Header + +data class WaitingPageDetailsResponse(@SerializedName("header") val header: Header? = null) diff --git a/navi-common/src/main/java/com/navi/common/network/ApiConstants.kt b/navi-common/src/main/java/com/navi/common/network/ApiConstants.kt index 341cc60fd6..8b28792263 100644 --- a/navi-common/src/main/java/com/navi/common/network/ApiConstants.kt +++ b/navi-common/src/main/java/com/navi/common/network/ApiConstants.kt @@ -1,8 +1,14 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.network import androidx.annotation.Keep - @Keep object ApiConstants { const val API_CONNECT_TIMEOUT_VALUE = 20L @@ -27,4 +33,4 @@ object ApiConstants { const val API_ERROR_SYSTEM_UNDER_MAINTENANCE_CODE = 503 const val API_WRONG_PROMO_CODE = 400 const val API_WRONG_ERROR_RESPONSE = 503 -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/network/BaseHttpClient.kt b/navi-common/src/main/java/com/navi/common/network/BaseHttpClient.kt index 76ec88bb44..0c0ffaf8fc 100644 --- a/navi-common/src/main/java/com/navi/common/network/BaseHttpClient.kt +++ b/navi-common/src/main/java/com/navi/common/network/BaseHttpClient.kt @@ -1,6 +1,7 @@ /* * - * Copyright (c) 2020 . All rights reserved @Navi + * * Copyright © 2020-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -10,14 +11,14 @@ import android.content.Context import android.os.Build import com.navi.analytics.utils.NaviAnalyticsHelper import com.navi.analytics.utils.NaviTrackEvent +import com.navi.base.utils.BaseUtils import com.navi.common.model.NetworkInfo import com.navi.common.network.NetworkErrorCode.NETWORK_CRASH_ERROR_CODE -import com.navi.base.utils.BaseUtils +import java.io.IOException +import java.util.concurrent.TimeUnit import okhttp3.* import okhttp3.MediaType.Companion.toMediaTypeOrNull import timber.log.Timber -import java.io.IOException -import java.util.concurrent.TimeUnit abstract class BaseHttpClient(private val networkInfo: NetworkInfo, private val context: Context) { val baseHttpClientBuilder: OkHttpClient.Builder @@ -37,27 +38,24 @@ abstract class BaseHttpClient(private val networkInfo: NetworkInfo, private val private val headerInterceptor: Interceptor get() = Interceptor { chain -> var request = chain.request() - val builder = request.headers.newBuilder().apply { - add("Content-Type", "application/json") - add("appVersion", networkInfo.appVersionName) - add("appVersionCode", networkInfo.appVersionCode) - add("osVersion", "Android_" + Build.VERSION.RELEASE) - add("deviceId", BaseUtils.getDeviceId(context)) - add("defaultLocale", BaseUtils.getDefaultLocale()) - BaseUtils.getSessionToken()?.let { - add("X-Session-Token", it) + val builder = + request.headers.newBuilder().apply { + add("Content-Type", "application/json") + add("appVersion", networkInfo.appVersionName) + add("appVersionCode", networkInfo.appVersionCode) + add("osVersion", "Android_" + Build.VERSION.RELEASE) + add("deviceId", BaseUtils.getDeviceId(context)) + add("defaultLocale", BaseUtils.getDefaultLocale()) + BaseUtils.getSessionToken()?.let { add("X-Session-Token", it) } + try { + add("X-Click-Stream-Data", NaviAnalyticsHelper.getClickStreamData()) + } catch (e: Exception) { + Timber.e(e) + } + networkInfo.moduleName?.name?.let { moduleName -> add("X-Target", moduleName) } + // TODO should removed. GI Backend can use X-Target + add("source", "APK") } - try { - add("X-Click-Stream-Data", NaviAnalyticsHelper.getClickStreamData()) - } catch (e: Exception) { - Timber.e(e) - } - networkInfo.moduleName?.name?.let { moduleName -> - add("X-Target", moduleName) - } - //TODO should removed. GI Backend can use X-Target - add("source", "APK") - } request = request.newBuilder().headers(builder.build()).build() try { chain.proceed(request) @@ -67,14 +65,12 @@ abstract class BaseHttpClient(private val networkInfo: NetworkInfo, private val mapOf(Pair("message", e.message.orEmpty())) ) // A mocked response in case of n/w exception - Response.Builder().request(request).protocol(Protocol.HTTP_2) + Response.Builder() + .request(request) + .protocol(Protocol.HTTP_2) .code(NETWORK_CRASH_ERROR_CODE) - .message(e.message.orEmpty()).body( - ResponseBody.create( - "application/json".toMediaTypeOrNull(), - "{}" - ) - ) + .message(e.message.orEmpty()) + .body(ResponseBody.create("application/json".toMediaTypeOrNull(), "{}")) .addHeader("content-type", "application/json") .build() } diff --git a/navi-common/src/main/java/com/navi/common/network/retrofit/ResponseCallback.kt b/navi-common/src/main/java/com/navi/common/network/retrofit/ResponseCallback.kt index 5bd2d9aadf..6a83c06d78 100644 --- a/navi-common/src/main/java/com/navi/common/network/retrofit/ResponseCallback.kt +++ b/navi-common/src/main/java/com/navi/common/network/retrofit/ResponseCallback.kt @@ -1,6 +1,7 @@ /* - * * - * * Copyright (c) 2019 . All rights reserved @Navi + * + * * Copyright © 2019-2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential * */ @@ -22,9 +23,9 @@ import com.navi.common.network.models.ErrorMessage import com.navi.common.network.models.RepoResult import com.navi.common.utils.isNetworkAvailable import com.navi.common.utils.orZero -import retrofit2.Response import java.net.ConnectException import java.net.SocketTimeoutException +import retrofit2.Response abstract class ResponseCallback { @@ -40,68 +41,52 @@ abstract class ResponseCallback { private fun handleResponse(response: Response>): RepoResult { response.body()?.let { if (it.statusCode.orZero() in API_SUCCESS_CODE until API_BAD_REQUEST) { - return RepoResult( - it.data, - null, - it.errors, - it.warning, - it.statusCode - ) + return RepoResult(it.data, null, it.errors, it.warning, it.statusCode) } else if (it.statusCode == API_ERROR_NO_USER_FOUND) { - //logged out or session expired here + // logged out or session expired here } return RepoResult( null, - ErrorMessage( - it.statusCode, - it.message, - it.message - ), + ErrorMessage(it.statusCode, it.message, it.message), it.errors, it.warning, it.statusCode ) - - } ?: run { - - if (response.code() == API_ERROR_NO_USER_FOUND) { - //logged out or session expired here - - return RepoResult() - } else if (response.code() == API_SUCCESS_CODE_204) { - return handleNoResponseBodySuccessResponse(response) - } else { - val gson = Gson() - val type = object : TypeToken>() {}.type - val errorResponse: GenericResponse? = - gson.fromJson(response.errorBody()?.charStream(), type) - return RepoResult( - null, - ErrorMessage(response.code(), response.message(), response.message()), - errorResponse?.errors, - null, - errorResponse?.statusCode - ) - } } + ?: run { + if (response.code() == API_ERROR_NO_USER_FOUND) { + // logged out or session expired here + + return RepoResult() + } else if (response.code() == API_SUCCESS_CODE_204) { + return handleNoResponseBodySuccessResponse(response) + } else { + val gson = Gson() + val type = object : TypeToken>() {}.type + val errorResponse: GenericResponse? = + gson.fromJson(response.errorBody()?.charStream(), type) + return RepoResult( + null, + ErrorMessage(response.code(), response.message(), response.message()), + errorResponse?.errors, + null, + errorResponse?.statusCode + ) + } + } } - private fun handleNoResponseBodySuccessResponse(response: Response>): RepoResult { - return RepoResult( - null, - null, - null, - null, - response.code() - ) + private fun handleNoResponseBodySuccessResponse( + response: Response> + ): RepoResult { + return RepoResult(null, null, null, null, response.code()) } private fun handleException(e: Exception): RepoResult { val result = RepoResult() val errorMessage = ErrorMessage() if (!isNetworkAvailable() || e is ConnectException) { - errorMessage.message = - CommonLibManager.application.getString(R.string.no_internet) + errorMessage.message = CommonLibManager.application.getString(R.string.no_internet) errorMessage.statusCode = NO_INTERNET } else if (e is SocketTimeoutException) { errorMessage.message = diff --git a/navi-common/src/main/java/com/navi/common/network/retrofit/RetrofitService.kt b/navi-common/src/main/java/com/navi/common/network/retrofit/RetrofitService.kt index d138514a37..6d2f67aea6 100644 --- a/navi-common/src/main/java/com/navi/common/network/retrofit/RetrofitService.kt +++ b/navi-common/src/main/java/com/navi/common/network/retrofit/RetrofitService.kt @@ -12,17 +12,19 @@ import com.navi.common.applicationplatform.model.ApGetNextCtaResponse import com.navi.common.applicationplatform.model.GetApplicationIdResponse import com.navi.common.awsupload.model.AWSPresignedUrlRequest import com.navi.common.awsupload.model.AWSPresignedUrlResponse -import com.navi.common.model.FeedbackResponse -import com.navi.common.model.FeedbackSubmitData -import com.navi.common.model.GenericResponse -import com.navi.common.model.ModuleName -import com.navi.common.model.PushNotificationData -import com.navi.common.model.UploadDataAsyncResponse +import com.navi.common.model.* +import com.navi.common.model.vkyc.VkycCancelStatus +import com.navi.common.model.vkyc.VkycSettingsResponse +import com.navi.common.model.vkyc.VkycStatus +import com.navi.common.model.vkyc.WaitingPageDetailsResponse import com.navi.common.network.models.SuccessResponse +import com.navi.common.permission.UpdateDevicePermissionsRequest +import com.navi.navi_vkyc.models.PermissionDetailsResponse import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Response import retrofit2.http.* +import retrofit2.http.Header interface RetrofitService { @@ -72,15 +74,58 @@ interface RetrofitService { @Header("X-Target") target: String = ModuleName.LE.name ): Response> + @POST("/dynamic-ui/applications") + suspend fun getApplicationId( + @Body bodyMap: HashMap, + @Header("X-Target") target: String = ModuleName.LE.name + ): Response> + @GET("/dynamic-ui/applications/{applicationId}/next-screen") suspend fun getNextCta( @Path("applicationId") applicationId: String, @Header("X-Target") target: String = ModuleName.LE.name ): Response> - @POST("/dynamic-ui/applications") - suspend fun getApplicationId( - @Body bodyMap: HashMap, - @Header("X-Target") target: String = ModuleName.LE.name - ): Response> + @GET("/customer-service/customers/me/vkyc-settings") + suspend fun fetchVkycSettings( + @Header("X-Target") target: String, + @Query("latitude") latitude: Double, + @Query("longitude") longitude: Double + ): Response> + + @GET("/customer-service/customers/me/vkyc-permission-page-details") + suspend fun fetchPermissionDetails( + @Header("X-Target") target: String + ): Response> + + @GET("/customer-service/customers/me/vkyc-waiting-page-details") + suspend fun fetchWaitingPageDetails( + @Header("X-Target") target: String + ): Response> + + @POST("/customer-service/customers/me/cancel-vkyc") + suspend fun cancelVkyc( + @Header("X-Target") target: String + ): Response> + + @GET("/customer-service/customers/me/navi-vkyc-status") + suspend fun fetchVkycStatus( + @Header("X-Target") target: String + ): Response> + + @GET("/customer-service/customers/me/vkyc-agent-assigned") + suspend fun fetchVkycAgentAssignedStatus( + @Header("X-Target") target: String + ): Response> + + @PATCH("/customer-service/customers/me/permission/submit/v1") + suspend fun submitPermission( + @Header("X-Target") target: String, + @Body updateDevicePermissionsRequest: UpdateDevicePermissionsRequest + ): Response> + + @GET("/status/ui-status") + suspend fun getRedirectPageStatus( + @Header("X-Target") target: String + ): Response> } diff --git a/navi-common/src/main/java/com/navi/common/permission/UpdateDevicePermissionsRequest.kt b/navi-common/src/main/java/com/navi/common/permission/UpdateDevicePermissionsRequest.kt new file mode 100644 index 0000000000..4c8ef0e4fb --- /dev/null +++ b/navi-common/src/main/java/com/navi/common/permission/UpdateDevicePermissionsRequest.kt @@ -0,0 +1,21 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.common.permission + +data class UpdateDevicePermissionsRequest(val permissionTypeGrantedList: List) + +data class Permission(val permissionTypeGranted: PermissionTypeGranted, val status: Boolean) + +enum class PermissionTypeGranted { + SMS, + CONTACTS, + DEVICE, + LOCATION, + CAMERA, + MICROPHONE +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/ControlTimedPoints.kt b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/ControlTimedPoints.kt index 7dfdf8cde2..9f013bc4b3 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/ControlTimedPoints.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/ControlTimedPoints.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -15,4 +15,4 @@ class ControlTimedPoints { this.c2 = c2 return this } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/CurveBezier.kt b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/CurveBezier.kt index 0b5fe3d644..8861166cb4 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/CurveBezier.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/CurveBezier.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,8 +13,10 @@ class CurveBezier { var control2: TimedPoint? = null var endPoint: TimedPoint? = null operator fun set( - startPoint: TimedPoint?, control1: TimedPoint?, - control2: TimedPoint?, endPoint: TimedPoint? + startPoint: TimedPoint?, + control1: TimedPoint?, + control2: TimedPoint?, + endPoint: TimedPoint? ): CurveBezier { this.startPoint = startPoint this.control1 = control1 @@ -34,14 +36,8 @@ class CurveBezier { var yDiff: Double for (i in 0..steps) { val t = i.toFloat() / steps - cx = point( - t, startPoint!!.x, control1!!.x, - control2!!.x, endPoint!!.x - ) - cy = point( - t, startPoint!!.y, control1!!.y, - control2!!.y, endPoint!!.y - ) + cx = point(t, startPoint!!.x, control1!!.x, control2!!.x, endPoint!!.x) + cy = point(t, startPoint!!.y, control1!!.y, control2!!.y, endPoint!!.y) if (i > 0) { xDiff = cx - px yDiff = cy - py @@ -54,6 +50,9 @@ class CurveBezier { } fun point(t: Float, start: Float, c1: Float, c2: Float, end: Float): Double { - return start * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * c1 * (1.0 - t) * (1.0 - t) * t + 3.0 * c2 * (1.0 - t) * t * t + end * t * t * t + return start * (1.0 - t) * (1.0 - t) * (1.0 - t) + + 3.0 * c1 * (1.0 - t) * (1.0 - t) * t + + 3.0 * c2 * (1.0 - t) * t * t + + end * t * t * t } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/TimedPoint.kt b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/TimedPoint.kt index 796580fe68..779e7eed96 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/TimedPoint.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/drawerControllers/TimedPoint.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -9,12 +9,9 @@ package com.navi.common.signaturepad.drawerControllers import com.navi.common.utils.orZero - class TimedPoint { - @JvmField - var x = 0f - @JvmField - var y = 0f + @JvmField var x = 0f + @JvmField var y = 0f var timestamp: Long = 0 operator fun set(x: Float, y: Float): TimedPoint { this.x = x @@ -30,10 +27,9 @@ class TimedPoint { fun distanceTo(point: TimedPoint?): Float { return Math.sqrt( - Math.pow((point?.x.orZero() - x).toDouble(), 2.0) + Math.pow( - (point?.y.orZero() - y).toDouble(), - 2.0 + Math.pow((point?.x.orZero() - x).toDouble(), 2.0) + + Math.pow((point?.y.orZero() - y).toDouble(), 2.0) ) - ).toFloat() + .toFloat() } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/svgUtils/SvgBuilder.kt b/navi-common/src/main/java/com/navi/common/signaturepad/svgUtils/SvgBuilder.kt index ac4fbcb567..451e645d73 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/svgUtils/SvgBuilder.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/svgUtils/SvgBuilder.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -24,7 +24,9 @@ class SvgBuilder { } return StringBuilder() .append("\n") - .append("? = null private var mIsEmpty = false private var mLastTouchX = 0f @@ -37,18 +36,18 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs private val mControlTimedPointsCached = ControlTimedPoints() private val mCurveBezierCached = CurveBezier() - //Configurable parameters + // Configurable parameters private var mMinWidth = 0 private var mMaxWidth = 0 private var mVelocityFilterWeight = 0f private var mOnSignedListener: OnSignedListener? = null private var mClearOnDoubleClick = false - //Click values + // Click values private var mFirstClick: Long = 0 private var mCountClick = 0 - //Default attribute values + // Default attribute values private val DEFAULT_ATTR_PEN_MIN_WIDTH_PX = 3 private val DEFAULT_ATTR_PEN_MAX_WIDTH_PX = 7 private val DEFAULT_ATTR_PEN_COLOR = Color.BLACK @@ -59,8 +58,8 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs private var mSignatureBitmapCanvas: Canvas? = null /** - * Set the pen color from a given resource. - * If the resource is not found, [Color.BLACK] is assumed. + * Set the pen color from a given resource. If the resource is not found, [Color.BLACK] is + * assumed. * * @param colorRes the color resource. */ @@ -150,7 +149,7 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs else -> return false } - //invalidate(); + // invalidate(); invalidate( (mDirtyRect.left - mMaxWidth).toInt(), (mDirtyRect.top - mMaxWidth).toInt(), @@ -191,9 +190,12 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs val signatureBitmap: Bitmap get() { val originalBitmap = transparentSignatureBitmap - val whiteBgBitmap = Bitmap.createBitmap( - originalBitmap!!.width, originalBitmap.height, Bitmap.Config.ARGB_8888 - ) + val whiteBgBitmap = + Bitmap.createBitmap( + originalBitmap!!.width, + originalBitmap.height, + Bitmap.Config.ARGB_8888 + ) val canvas = Canvas(whiteBgBitmap) canvas.drawColor(Color.WHITE) canvas.drawBitmap(originalBitmap, 0f, 0f, null) @@ -201,10 +203,9 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs } /** - * @param compressPercentage Hint to the compressor, 0-100 percent. 0 meaning compress for - * small size, 100 meaning compress for max quality. Some - * formats, like PNG which is lossless, will ignore the - * quality setting + * @param compressPercentage Hint to the compressor, 0-100 percent. 0 meaning compress for small + * size, 100 meaning compress for max quality. Some formats, like PNG which is lossless, will + * ignore the quality setting */ fun getCompressedSignatureBitmap(compressPercentage: Int): Bitmap { var compressPercentage = compressPercentage @@ -227,27 +228,24 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs return whiteBgBitmap } - /** - * @param deiredWidth Desired width of the bitmap - */ + /** @param deiredWidth Desired width of the bitmap */ fun getFixedSizeSignatureBitmap(deiredWidth: Int): Bitmap { val originalBitmap = transparentSignatureBitmap val originalWidth = originalBitmap!!.width val originalHeight = originalBitmap.height - val targetHeight = (originalHeight * deiredWidth // your arbitrary fixed limit - / originalWidth.toDouble()).toInt() + val targetHeight = + (originalHeight * deiredWidth // your arbitrary fixed limit + / originalWidth.toDouble()) + .toInt() var whiteBgBitmap = Bitmap.createBitmap(originalWidth, originalHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(whiteBgBitmap) canvas.drawColor(Color.WHITE) canvas.drawBitmap(originalBitmap, 0f, 0f, null) - whiteBgBitmap = Bitmap.createScaledBitmap( - originalBitmap, deiredWidth, targetHeight, true - ) + whiteBgBitmap = Bitmap.createScaledBitmap(originalBitmap, deiredWidth, targetHeight, true) return whiteBgBitmap } - val transparentSignatureBitmap: Bitmap? get() { ensureSignatureBitmap() @@ -329,7 +327,10 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs private val isDoubleClick: Boolean private get() { if (mClearOnDoubleClick) { - if (mFirstClick != 0L && System.currentTimeMillis() - mFirstClick > DOUBLE_CLICK_DELAY_MS) { + if ( + mFirstClick != 0L && + System.currentTimeMillis() - mFirstClick > DOUBLE_CLICK_DELAY_MS + ) { mCountClick = 0 } mCountClick++ @@ -349,13 +350,14 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs private fun getNewPoint(x: Float, y: Float): TimedPoint { val mCacheSize = mPointsCache.size val timedPoint: TimedPoint? - timedPoint = if (mCacheSize == 0) { - // Cache is empty, create a new point - TimedPoint() - } else { - // Get point from cache - mPointsCache.removeAt(mCacheSize - 1) - } + timedPoint = + if (mCacheSize == 0) { + // Cache is empty, create a new point + TimedPoint() + } else { + // Get point from cache + mPointsCache.removeAt(mCacheSize - 1) + } return timedPoint!!.set(x, y) } @@ -378,8 +380,8 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs val endPoint = curve.endPoint var velocity = endPoint!!.velocityFrom(startPoint) velocity = if (java.lang.Float.isNaN(velocity)) 0.0f else velocity - velocity = (mVelocityFilterWeight * velocity - + (1 - mVelocityFilterWeight) * mLastVelocity) + velocity = + (mVelocityFilterWeight * velocity + (1 - mVelocityFilterWeight) * mLastVelocity) // The new width is a function of the velocity. Higher velocities // correspond to thinner strokes. @@ -474,8 +476,7 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs } /** - * Called when replaying history to ensure the dirty region includes all - * mPoints. + * Called when replaying history to ensure the dirty region includes all mPoints. * * @param historicalX the previous x coordinate. * @param historicalY the previous y coordinate. @@ -510,13 +511,8 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs private fun ensureSignatureBitmap() { if (mSignatureBitmap == null) { - mSignatureBitmap = Bitmap.createBitmap( - width, height, - Bitmap.Config.ARGB_8888 - ) - mSignatureBitmap?.let { - mSignatureBitmapCanvas = Canvas(it) - } + mSignatureBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + mSignatureBitmap?.let { mSignatureBitmapCanvas = Canvas(it) } } } @@ -529,46 +525,44 @@ class SignaturePad(context: Context, attrs: AttributeSet?) : View(context, attrs } init { - val a = context.theme.obtainStyledAttributes( - attrs, - R.styleable.SilkySignaturePad, - 0, 0 - ) + val a = context.theme.obtainStyledAttributes(attrs, R.styleable.SilkySignaturePad, 0, 0) - //Configurable parameters + // Configurable parameters try { - mMinWidth = a.getDimensionPixelSize( - R.styleable.SilkySignaturePad_penMinWidth, - convertDpToPx(DEFAULT_ATTR_PEN_MIN_WIDTH_PX.toFloat()) - ) - mMaxWidth = a.getDimensionPixelSize( - R.styleable.SilkySignaturePad_penMaxWidth, - convertDpToPx(DEFAULT_ATTR_PEN_MAX_WIDTH_PX.toFloat()) - ) - mPaint.color = a.getColor( - R.styleable.SilkySignaturePad_penColor, - DEFAULT_ATTR_PEN_COLOR - ) - mVelocityFilterWeight = a.getFloat( - R.styleable.SilkySignaturePad_velocityFilterWeight, - DEFAULT_ATTR_VELOCITY_FILTER_WEIGHT - ) - mClearOnDoubleClick = a.getBoolean( - R.styleable.SilkySignaturePad_clearOnDoubleClick, - DEFAULT_ATTR_CLEAR_ON_DOUBLE_CLICK - ) + mMinWidth = + a.getDimensionPixelSize( + R.styleable.SilkySignaturePad_penMinWidth, + convertDpToPx(DEFAULT_ATTR_PEN_MIN_WIDTH_PX.toFloat()) + ) + mMaxWidth = + a.getDimensionPixelSize( + R.styleable.SilkySignaturePad_penMaxWidth, + convertDpToPx(DEFAULT_ATTR_PEN_MAX_WIDTH_PX.toFloat()) + ) + mPaint.color = + a.getColor(R.styleable.SilkySignaturePad_penColor, DEFAULT_ATTR_PEN_COLOR) + mVelocityFilterWeight = + a.getFloat( + R.styleable.SilkySignaturePad_velocityFilterWeight, + DEFAULT_ATTR_VELOCITY_FILTER_WEIGHT + ) + mClearOnDoubleClick = + a.getBoolean( + R.styleable.SilkySignaturePad_clearOnDoubleClick, + DEFAULT_ATTR_CLEAR_ON_DOUBLE_CLICK + ) } finally { a.recycle() } - //Fixed parameters + // Fixed parameters mPaint.isAntiAlias = true mPaint.style = Paint.Style.STROKE mPaint.strokeCap = Paint.Cap.ROUND mPaint.strokeJoin = Paint.Join.ROUND - //Dirty rectangle to update only the changed portion of the view + // Dirty rectangle to update only the changed portion of the view mDirtyRect = RectF() clear() } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewCompat.kt b/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewCompat.kt index 7cdc439bff..7ee9a8e9a2 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewCompat.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewCompat.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -18,4 +18,4 @@ object ViewCompat { } else view.width > 0 && view.height > 0 // Legacy... } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewTreeObserverCompat.kt b/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewTreeObserverCompat.kt index 6b3e8d3fc2..ae47d03129 100644 --- a/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewTreeObserverCompat.kt +++ b/navi-common/src/main/java/com/navi/common/signaturepad/viewHelper/ViewTreeObserverCompat.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -24,4 +24,4 @@ object ViewTreeObserverCompat { observer.removeGlobalOnLayoutListener(victim) } } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/ui/fragment/BaseBottomSheet.kt b/navi-common/src/main/java/com/navi/common/ui/fragment/BaseBottomSheet.kt index 814975e69b..fd6ac52c45 100644 --- a/navi-common/src/main/java/com/navi/common/ui/fragment/BaseBottomSheet.kt +++ b/navi-common/src/main/java/com/navi/common/ui/fragment/BaseBottomSheet.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -74,8 +74,7 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setStyle(STYLE_NORMAL, R.style.SheetDialog) - if (screenName.isNotBlank()) - NaviTrackEvent.startScreen(screenName) + if (screenName.isNotBlank()) NaviTrackEvent.startScreen(screenName) } override fun onCreateView( @@ -84,9 +83,7 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { savedInstanceState: Bundle? ): View? { binding = BaseBottomSheetFragmentBinding.inflate(inflater, container, false) - binding.containerVs.viewStub?.let { - setContainerView(it) - } + binding.containerVs.viewStub?.let { setContainerView(it) } return binding.root } @@ -106,8 +103,7 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { binding.containerFl.setPadding(left, top, right, bottom) } - fun hideTopDivider() { - } + fun hideTopDivider() {} override fun onCancel(dialog: DialogInterface) { onCancelListener?.handleDialogCancel() @@ -127,4 +123,4 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { const val TAG = "ACTION_BOTTOM_DIALOG_FRAGMENT" private const val MIN_HEIGHT_RATIO = 0.25 } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/ui/fragment/BaseFragment.kt b/navi-common/src/main/java/com/navi/common/ui/fragment/BaseFragment.kt index b3f353434d..66e8e2885e 100644 --- a/navi-common/src/main/java/com/navi/common/ui/fragment/BaseFragment.kt +++ b/navi-common/src/main/java/com/navi/common/ui/fragment/BaseFragment.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -28,8 +28,8 @@ import com.navi.common.utils.ErrorNavigator import com.navi.common.utils.getTimeOutErrorData import com.navi.common.utils.orTrue import com.navi.common.viewmodel.BaseVM -import timber.log.Timber import java.lang.ref.WeakReference +import timber.log.Timber abstract class BaseFragment : Fragment() { @@ -107,8 +107,7 @@ abstract class BaseFragment : Fragment() { apiPollScheduler: ApiPollScheduler?, isLoaderHide: Boolean = true ) { - if (isLoaderHide) - hideLoader() + if (isLoaderHide) hideLoader() apiPollScheduler?.stopApiPoll() firebaseDataHelper?.clear() } @@ -122,10 +121,7 @@ abstract class BaseFragment : Fragment() { try { deInitializeAsyncListeners(firebaseDataHelper, apiPollScheduler) context?.let { - showErrorScreen( - getTimeOutErrorData(it), - listOf(Pair(clickListener, errorTag)) - ) + showErrorScreen(getTimeOutErrorData(it), listOf(Pair(clickListener, errorTag))) } } catch (e: Exception) { Timber.e(e) @@ -145,8 +141,7 @@ abstract class BaseFragment : Fragment() { super.onCreate(savedInstanceState) latencyMapper = LatencyMapper(screenName) lifecycle.addObserver(latencyMapper) - if (screenName.isNotBlank()) - NaviTrackEvent.startScreen(screenName) + if (screenName.isNotBlank()) NaviTrackEvent.startScreen(screenName) NaviTrackEvent.sendScreenTransitionEvent(screenName) setupQueryMap() } @@ -161,9 +156,7 @@ abstract class BaseFragment : Fragment() { override fun onResume() { super.onResume() - context?.let { - MoengageUtil.showInApp(WeakReference(it)) - } + context?.let { MoengageUtil.showInApp(WeakReference(it)) } } protected fun safelyShowBottomSheet( @@ -205,17 +198,11 @@ abstract class BaseFragment : Fragment() { fragmentInterchangeListener: FragmentInterchangeListener? ) { val bundle = Bundle() - ctaData.parameters?.forEach { - bundle.putString(it.key, it.value) - } - ctaData.url?.let { - fragmentInterchangeListener?.navigateToNextScreen(it, bundle) - } + ctaData.parameters?.forEach { bundle.putString(it.key, it.value) } + ctaData.url?.let { fragmentInterchangeListener?.navigateToNextScreen(it, bundle) } } - /** - * Returns true if feedback sheet was shown - * */ + /** Returns true if feedback sheet was shown */ protected fun openFeedbackFragment(): Boolean = (context as? BaseActivity)?.openFeedbackFragment().orFalse() @@ -242,8 +229,6 @@ abstract class BaseFragment : Fragment() { private fun setupQueryMap() { queryMap.clear() - arguments?.keySet()?.forEach { key -> - queryMap[key] = "${arguments?.get(key)}" - } + arguments?.keySet()?.forEach { key -> queryMap[key] = "${arguments?.get(key)}" } } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/ui/fragment/SingleSelectionBottomSheet.kt b/navi-common/src/main/java/com/navi/common/ui/fragment/SingleSelectionBottomSheet.kt index 4d79cea531..9a02180596 100644 --- a/navi-common/src/main/java/com/navi/common/ui/fragment/SingleSelectionBottomSheet.kt +++ b/navi-common/src/main/java/com/navi/common/ui/fragment/SingleSelectionBottomSheet.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.ui.fragment import android.os.Bundle @@ -58,4 +65,4 @@ class SingleSelectionBottomSheet : BaseBottomSheet() { } } } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/utils/BindingAdapter.kt b/navi-common/src/main/java/com/navi/common/utils/BindingAdapter.kt index 80cbb307ee..b2a6628ec5 100644 --- a/navi-common/src/main/java/com/navi/common/utils/BindingAdapter.kt +++ b/navi-common/src/main/java/com/navi/common/utils/BindingAdapter.kt @@ -1,15 +1,26 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.common.utils +import android.graphics.Color import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.TextView import androidx.appcompat.widget.AppCompatTextView import androidx.core.view.isVisible import androidx.databinding.BindingAdapter import com.google.android.material.card.MaterialCardView import com.navi.base.model.ActionData import com.navi.common.extensions.isNotNull +import com.navi.common.listeners.ClickableTextListener import com.navi.common.model.LabelData +import com.navi.common.model.StyledTextWithIconCode import com.navi.design.textview.NaviTextView import com.navi.design.textview.model.TextWithStyle import com.navi.design.utils.dpToPx @@ -17,6 +28,7 @@ import com.navi.design.utils.getNaviDrawable import com.navi.design.utils.parseColorSafe import com.navi.design.utils.setSpannableString import com.navi.naviwidgets.extensions.setSpannableString +import com.navi.naviwidgets.utils.NaviWidgetIconUtils @BindingAdapter("visibility") fun setVisibility(view: View, isVisible: Boolean) { @@ -60,6 +72,43 @@ fun setMaterialCardStroke(materialCardView: MaterialCardView, strokeWidth: Float materialCardView.strokeWidth = strokeWidth.toInt() } +@BindingAdapter("setImageFromIconCodeCommon") +fun setImageFromIconCodeCommon(imageView: ImageView, iconCode: String?) { + iconCode?.let { + imageView.visibility = View.VISIBLE + NaviWidgetIconUtils.updateIcon(it, imageView) + } + ?: run { imageView.visibility = View.GONE } +} + +// TODO Create a generic version here +@BindingAdapter("setStyledText", "setClickableTextListener", requireAll = false) +fun setStyledText( + textView: TextView, + styledTextWithIconCode: StyledTextWithIconCode?, + clickableTextListener: ClickableTextListener? +) { + styledTextWithIconCode?.let { + it.text?.let { text -> textView.text = text } + it.hexColorCode?.let { hexColorCode -> + try { + textView.setTextColor(Color.parseColor(hexColorCode)) + } catch (e: Exception) { + e.log() + } + } + + it.boldText?.let { boldText -> + it.text?.let { text -> textView.makePartOfTextBold(text, boldText) } + } + it.boldTextList?.let { boldText -> + it.text?.let { text -> textView.makePartOfTextBold(text, boldText) } + } + + textView.spannableString(it, clickableTextListener) + } +} + @BindingAdapter("setTextWithStyle") fun setTextWithStyle(textView: NaviTextView, textData: TextWithStyle?) { textView.setSpannableString(textData) @@ -69,16 +118,16 @@ fun setTextWithStyle(textView: NaviTextView, textData: TextWithStyle?) { fun setActionData(view: NaviTextView, data: ActionData?) { data?.let { view.visibility = View.VISIBLE - val background = getNaviDrawable( - cornerRadius = dpToPx(24).toInt(), - backgroundColor = data.bgColor.parseColorSafe() - ) + val background = + getNaviDrawable( + cornerRadius = dpToPx(24).toInt(), + backgroundColor = data.bgColor.parseColorSafe() + ) view.background = background view.text = data.title view.setTextColor(data.titleColor.parseColorSafe()) - } ?: run { - view.visibility = View.GONE } + ?: run { view.visibility = View.GONE } } @BindingAdapter("setLabelData") @@ -90,13 +139,13 @@ fun setLabelData(view: NaviTextView, data: LabelData?) { val strokeColor = if (data.borderColor.isNotNull()) data.borderColor.parseColorSafe() else null val strokeWidth = if (strokeColor.isNotNull()) dpToPx(1).toInt() else null - view.background = getNaviDrawable( - cornerRadius = dpToPx(12).toInt(), - backgroundColor = backgroundColor, - strokeColor = strokeColor, - strokeWidth = strokeWidth - ) - } ?: run{ - (view as AppCompatTextView).isVisible = false + view.background = + getNaviDrawable( + cornerRadius = dpToPx(12).toInt(), + backgroundColor = backgroundColor, + strokeColor = strokeColor, + strokeWidth = strokeWidth + ) } -} \ No newline at end of file + ?: run { (view as AppCompatTextView).isVisible = false } +} diff --git a/navi-common/src/main/java/com/navi/common/utils/CommonNaviAnalytics.kt b/navi-common/src/main/java/com/navi/common/utils/CommonNaviAnalytics.kt index e75bcd8e56..f966355a65 100644 --- a/navi-common/src/main/java/com/navi/common/utils/CommonNaviAnalytics.kt +++ b/navi-common/src/main/java/com/navi/common/utils/CommonNaviAnalytics.kt @@ -35,12 +35,11 @@ class CommonNaviAnalytics private constructor() { error: GenericErrorResponse?, errorMessage: ErrorMessage? ) { - val map = - mapOf( - Pair("error_data", error.toString()), - Pair("message", errorMessage.toString()) - ) - NaviTrackEvent.trackEventOnClickStream(eventName, map) + val map = mapOf( + Pair("error_data", error.toString()), + Pair("message", errorMessage.toString()) + ) + NaviTrackEvent.trackEvent(eventName, map) } } @@ -456,13 +455,14 @@ class CommonNaviAnalytics private constructor() { } fun timeSpendOnScreen( + eventName: String?, screenName: String, loanApplicationId: String, loanType: String, duration: String ) { NaviTrackEvent.trackEventOnClickStream( - "HL_Screen_Activity", + eventName ?: "HL_Screen_Activity", mapOf( Pair("screen_name", screenName), Pair("loan_application_id", loanApplicationId), diff --git a/navi-common/src/main/java/com/navi/common/utils/Ext.kt b/navi-common/src/main/java/com/navi/common/utils/Ext.kt index 634e462bf5..571861fb60 100644 --- a/navi-common/src/main/java/com/navi/common/utils/Ext.kt +++ b/navi-common/src/main/java/com/navi/common/utils/Ext.kt @@ -10,6 +10,7 @@ package com.navi.common.utils import android.app.Activity import android.content.Context import android.graphics.Color +import android.graphics.Outline import android.graphics.drawable.GradientDrawable import android.os.Handler import android.text.Spannable @@ -21,10 +22,11 @@ import android.text.style.* import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.ViewOutlineProvider import android.view.inputmethod.InputMethodManager import android.widget.EditText -import androidx.core.content.ContextCompat import android.widget.TextView +import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding @@ -41,9 +43,10 @@ import com.navi.common.customview.CustomTypefaceSpan import com.navi.common.listeners.ClickableTextListener import com.navi.common.model.StyledTextWithIconCode import com.navi.common.network.retrofit.RetrofitService +import com.navi.design.font.FontWeightEnum +import com.navi.design.utils.getFontStyle import com.navi.naviwidgets.extensions.getOrientation import com.navi.naviwidgets.models.response.Gradient -import com.navi.design.utils.getFontStyle import java.io.ByteArrayOutputStream import java.util.* import java.util.zip.GZIPOutputStream @@ -233,16 +236,11 @@ fun isFirstWordInUpperCase(text: String): Boolean { return words[0] == words[0].uppercase() } - fun getOtpBoxMargin(otpSize: Int): Int { - if (otpSize <= 4) - return 16 - else if (otpSize <= 6) - return 10 + if (otpSize <= 4) return 16 else if (otpSize <= 6) return 10 return 5 } - fun makeFirstWordLowerCase(text: String): String { if (text.isNotEmpty()) { val firstChar = text[0] @@ -273,9 +271,8 @@ fun Activity.setStatusBarColor(color: Int) { fun Activity.setStatusBarColor(startColor: Int, endColor: Int, orientation: String?) { val colors: IntArray = intArrayOf(startColor, endColor) - window.statusBarColor = resources.getColor(android.R.color.transparent); + window.statusBarColor = resources.getColor(android.R.color.transparent) window.setBackgroundDrawable(GradientDrawable(getOrientation(orientation), colors)) - } fun Fragment.setStatusBarColor(gradient: Gradient) { @@ -399,4 +396,49 @@ fun TextView.spannableString( } catch (e: Exception) { e.log() } -} \ No newline at end of file +} + +fun View.setCornerRadius(radiusInPixels: Number) { + try { + clipToOutline = true + outlineProvider = + object : ViewOutlineProvider() { + override fun getOutline(view: View?, outline: Outline?) { + view?.let { + outline?.setRoundRect( + 0, + 0, + view.width, + view.height, + radiusInPixels.toFloat() + ) + } + } + } + } catch (e: Exception) { + e.log() + } +} + +fun TextView.makePartOfTextBold(text: String, boldTexts: List?) { + try { + val naviBold = ResourcesCompat.getFont(this.context, getFontStyle(FontWeightEnum.BOLD.name)) + naviBold?.let { naviBoldTypeFace -> + val content = SpannableString(text) + boldTexts?.forEach { boldText -> + val naviBoldSpan = CustomTypefaceSpan(naviBoldTypeFace) + val startIndex = text.indexOf(boldText) + content.setSpan( + naviBoldSpan, + startIndex, + startIndex + boldText.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + this.setText(content, TextView.BufferType.SPANNABLE) + } + } catch (e: Exception) { + this.setText(text) + e.log() + } +} diff --git a/navi-common/src/main/java/com/navi/common/utils/FileHelper.kt b/navi-common/src/main/java/com/navi/common/utils/FileHelper.kt index 3776e9caf6..96f41825ed 100644 --- a/navi-common/src/main/java/com/navi/common/utils/FileHelper.kt +++ b/navi-common/src/main/java/com/navi/common/utils/FileHelper.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.common.utils import android.content.ContentResolver @@ -14,18 +15,13 @@ import android.webkit.MimeTypeMap import com.navi.base.utils.orFalse import com.navi.common.awsupload.AWSFileType import com.navi.common.di.CoroutineDispatcherProvider +import java.io.File +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import timber.log.Timber -import java.io.File -import javax.inject.Inject - -class FileHelper -@Inject -constructor( - private val dispatcher: CoroutineDispatcherProvider -) { +class FileHelper @Inject constructor(private val dispatcher: CoroutineDispatcherProvider) { fun generateFileForCamera( context: Context, @@ -65,9 +61,8 @@ constructor( val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) cursor.moveToFirst() cursor.getLong(sizeIndex) - } ?: run { - -1L } + ?: run { -1L } } } @@ -84,7 +79,6 @@ constructor( } } - suspend fun getFileExtension( context: Context, uri: Uri, @@ -101,9 +95,7 @@ constructor( } } - fun getExtensionFromFileName( - fileName: String - ): String { + fun getExtensionFromFileName(fileName: String): String { return fileName.substring(fileName.lastIndexOf(".") + 1) } @@ -117,6 +109,5 @@ constructor( const val DOCX_EXTENSION = "docx" const val ODT_EXTENSION = "odt" const val BMP_EXTENSION = "bmp" - } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/utils/InAppUpdate.kt b/navi-common/src/main/java/com/navi/common/utils/InAppUpdate.kt index 4a01119ad7..1ee3bace67 100644 --- a/navi-common/src/main/java/com/navi/common/utils/InAppUpdate.kt +++ b/navi-common/src/main/java/com/navi/common/utils/InAppUpdate.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2019 by Navi Technologies Private Limited + * * Copyright © 2019-2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -32,12 +32,14 @@ class InAppUpdate(application: Application) : LifecycleObserver { private val naviAnalyticsInAppUpdate by lazy { CommonNaviAnalytics.naviAnalytics.InAppUpdate() } private val listenerForFlexibleUpdate by lazy { InstallStateUpdatedListener { state -> - if (state.installStatus() == InstallStatus.DOWNLOADED && - ::inAppUpdateListener.isInitialized + if ( + state.installStatus() == InstallStatus.DOWNLOADED && + ::inAppUpdateListener.isInitialized ) { inAppUpdateListener.showInstallAppSnackBar() - } else if (state.installStatus() == InstallStatus.CANCELED || - state.installStatus() == InstallStatus.FAILED + } else if ( + state.installStatus() == InstallStatus.CANCELED || + state.installStatus() == InstallStatus.FAILED ) { naviAnalyticsInAppUpdate.onInAppFailed() } @@ -46,8 +48,7 @@ class InAppUpdate(application: Application) : LifecycleObserver { private lateinit var inAppUpdateListener: InAppUpdateListener init { - AppUpdateManagerFactory.create(application) - .also { appUpdateManager = it } + AppUpdateManagerFactory.create(application).also { appUpdateManager = it } appUpdateInfoTask = appUpdateManager.appUpdateInfo } @@ -69,8 +70,9 @@ class InAppUpdate(application: Application) : LifecycleObserver { fun getAppUpdateInProgress() = appUpdateInfo?.installStatus() == InstallStatus.DOWNLOADING || - appUpdateInfo?.installStatus() == InstallStatus.INSTALLING || - appUpdateInfo?.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS + appUpdateInfo?.installStatus() == InstallStatus.INSTALLING || + appUpdateInfo?.updateAvailability() == + UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS fun completeUpdate() { appUpdateManager.completeUpdate() @@ -78,17 +80,13 @@ class InAppUpdate(application: Application) : LifecycleObserver { fun checkForUpdate( screenName: String, - updateApp: ( - String, - Boolean, showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? - ) -> Unit, - showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? = null, + updateApp: + ( + String, + Boolean, + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? + ) -> Unit, + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? = null, showBadge: (Int, Boolean) -> Unit ) { appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> @@ -107,10 +105,7 @@ class InAppUpdate(application: Application) : LifecycleObserver { fun updateApp( inAppUpdateResponse: InAppUpdateResponse, - showDialog: (( - UpdateAppDetails, - startUpdatingApp: () -> Unit - ) -> Unit)? = null + showDialog: ((UpdateAppDetails, startUpdatingApp: () -> Unit) -> Unit)? = null ) { if (inAppUpdateResponse.enable.orFalse()) { val appUpdateType = @@ -119,8 +114,9 @@ class InAppUpdate(application: Application) : LifecycleObserver { } else { AppUpdateType.FLEXIBLE } - checkForAppUpdate(appUpdateType) { appUpdateManager: AppUpdateManager, - appUpdateInfo: AppUpdateInfo -> + checkForAppUpdate(appUpdateType) { + appUpdateManager: AppUpdateManager, + appUpdateInfo: AppUpdateInfo -> inAppUpdateResponse.updateAppDetails?.let { showDialog?.invoke(it) { startUpdatingApp( @@ -128,11 +124,12 @@ class InAppUpdate(application: Application) : LifecycleObserver { appUpdateInfo = appUpdateInfo, appUpdateType = appUpdateType ) - } ?: startUpdatingApp( - appUpdateManager = appUpdateManager, - appUpdateInfo = appUpdateInfo, - appUpdateType = appUpdateType - ) + } + ?: startUpdatingApp( + appUpdateManager = appUpdateManager, + appUpdateInfo = appUpdateInfo, + appUpdateType = appUpdateType + ) } } } @@ -144,8 +141,9 @@ class InAppUpdate(application: Application) : LifecycleObserver { ) { appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> this.appUpdateInfo = appUpdateInfo - if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && - appUpdateInfo.isUpdateTypeAllowed(appUpdateType) + if ( + appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && + appUpdateInfo.isUpdateTypeAllowed(appUpdateType) ) { updateApp.invoke(appUpdateManager, appUpdateInfo) } @@ -172,18 +170,20 @@ class InAppUpdate(application: Application) : LifecycleObserver { getAppUpdateInfo().addOnSuccessListener { state -> this.appUpdateInfo = state if (state.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) { - if (state.installStatus() == InstallStatus.DOWNLOADED && - ::inAppUpdateListener.isInitialized + if ( + state.installStatus() == InstallStatus.DOWNLOADED && + ::inAppUpdateListener.isInitialized ) { inAppUpdateListener.showInstallAppSnackBar() } else { - getAppUpdateManager() - .registerListener(listenerForFlexibleUpdate) + getAppUpdateManager().registerListener(listenerForFlexibleUpdate) } } - if (state.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) && state.updateAvailability() - == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS + if ( + state.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) && + state.updateAvailability() == + UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS ) { inAppUpdateListener.startImmediateInAppUpdate( appUpdateManager = getAppUpdateManager(), @@ -219,4 +219,4 @@ class InAppUpdate(application: Application) : LifecycleObserver { fun onDestroy() { unRegisterInstallStateUpdatedListener() } -} \ No newline at end of file +} diff --git a/navi-common/src/main/java/com/navi/common/video/NaviYoutubeActivity.kt b/navi-common/src/main/java/com/navi/common/video/NaviYoutubeActivity.kt index 9e79510bf1..af914044c6 100644 --- a/navi-common/src/main/java/com/navi/common/video/NaviYoutubeActivity.kt +++ b/navi-common/src/main/java/com/navi/common/video/NaviYoutubeActivity.kt @@ -64,7 +64,7 @@ class NaviYoutubeActivity : YouTubeBaseActivity(), OnInitializedListener { restored: Boolean ) { youTubePlayer = player - youTubePlayer?.setPlayerStyle(PlayerStyle.DEFAULT) + youTubePlayer?.setPlayerStyle(PlayerStyle.MINIMAL) youTubePlayer?.setShowFullscreenButton(true) youTubePlayer?.addFullscreenControlFlag(FULLSCREEN_FLAG_CONTROL_ORIENTATION) youTubePlayer?.addFullscreenControlFlag(FULLSCREEN_FLAG_CONTROL_SYSTEM_UI) @@ -112,7 +112,7 @@ class NaviYoutubeActivity : YouTubeBaseActivity(), OnInitializedListener { override fun onVideoEnded() { handleStopEvent() - youTubePlayer?.cueVideo(videoId) + onBackPressed() } override fun onError(errorReason: ErrorReason) { diff --git a/navi-common/src/main/res/values/styles.xml b/navi-common/src/main/res/values/styles.xml index a92bd194c8..d17ca0ade6 100644 --- a/navi-common/src/main/res/values/styles.xml +++ b/navi-common/src/main/res/values/styles.xml @@ -13,6 +13,13 @@ @color/title_color_one + + + + + + + + @@ -395,4 +413,21 @@ @dimen/sp_16 + + + + \ No newline at end of file diff --git a/navi-vkyc/.gitignore b/navi-vkyc/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/navi-vkyc/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/navi-vkyc/build.gradle b/navi-vkyc/build.gradle new file mode 100644 index 0000000000..37e127617d --- /dev/null +++ b/navi-vkyc/build.gradle @@ -0,0 +1,63 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-kapt' + id 'kotlin-android-extensions' + id 'dagger.hilt.android.plugin' +} + +android { + compileSdkVersion 32 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 31 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + incremental true + } + kotlinOptions { + jvmTarget = '1.8' + } + + buildFeatures { + dataBinding true + } +} + +dependencies { + + implementation project(":navi-common") + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + implementation hiltLibs.implementation + kapt hiltLibs.kapt + + implementation hiltLibs.androidTest + kapt hiltLibs.kaptAndroidTest + + implementation hiltLibs.test + kapt hiltLibs.kaptTest + + implementation fragmentLibs.ktx + + implementation "com.github.100mslive.android-sdk:lib:2.5.1" + +} diff --git a/navi-vkyc/proguard-rules.pro b/navi-vkyc/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/navi-vkyc/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/navi-vkyc/src/androidTest/java/com/example/navi_vkyc/ExampleInstrumentedTest.kt b/navi-vkyc/src/androidTest/java/com/example/navi_vkyc/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..ff2515a9a4 --- /dev/null +++ b/navi-vkyc/src/androidTest/java/com/example/navi_vkyc/ExampleInstrumentedTest.kt @@ -0,0 +1,29 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.example.navi_vkyc + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.navi_vkyc", appContext.packageName) + } +} diff --git a/navi-vkyc/src/main/AndroidManifest.xml b/navi-vkyc/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..b3807a96c5 --- /dev/null +++ b/navi-vkyc/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/Constants.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/Constants.kt new file mode 100644 index 0000000000..52515792a8 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/Constants.kt @@ -0,0 +1,17 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.common + +object Constants { + const val PACKAGE = "package:" + const val VKYC_VENDOR_NAME = "NAVI" + const val APPLICATION_ID = "APPLICATION_ID" + const val MODULE_NAME = "MODULE_NAME" + const val LATITUDE = "LATITUDE" + const val LONGITUDE = "LONGITUDE" +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/VkycScreens.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/VkycScreens.kt new file mode 100644 index 0000000000..aca10edf65 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/common/VkycScreens.kt @@ -0,0 +1,15 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.common + +enum class VkycScreens { + VKYC_PERMISSIONS_SCREEN, + VKYC_WAITING_FOR_EXECUTIVE_SCREEN, + VKYC_MEETING_ROOM, + VKYC_STATUS_CHECK_SCREEN +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/data/VkycRepository.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/data/VkycRepository.kt new file mode 100644 index 0000000000..ebc9b31713 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/data/VkycRepository.kt @@ -0,0 +1,37 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.data + +import com.navi.common.network.retrofit.ResponseCallback +import com.navi.common.permission.UpdateDevicePermissionsRequest +import com.navi.common.utils.retrofitService +import javax.inject.Inject + +class VkycRepository @Inject constructor() : ResponseCallback() { + suspend fun fetchVkycSettings(callingModule: String, latitude: Double, longitude: Double) = + apiResponseCallback(retrofitService().fetchVkycSettings(callingModule, latitude, longitude)) + suspend fun fetchPermissionDetails(callingModule: String) = + apiResponseCallback(retrofitService().fetchPermissionDetails(callingModule)) + suspend fun fetchWaitingPageDetails(callingModule: String) = + apiResponseCallback(retrofitService().fetchWaitingPageDetails(callingModule)) + suspend fun cancelVkyc(callingModule: String) = + apiResponseCallback(retrofitService().cancelVkyc(callingModule)) + suspend fun fetchVkycStatus(callingModule: String) = + apiResponseCallback(retrofitService().fetchVkycStatus(callingModule)) + suspend fun fetchVkycAgentAssignedStatus(callingModule: String) = + apiResponseCallback(retrofitService().fetchVkycAgentAssignedStatus(callingModule)) + suspend fun fetchKycStatus(callingModule: String) = + apiResponseCallback(retrofitService().getRedirectPageStatus(callingModule)) + suspend fun submitPermission( + callingModule: String, + updateDevicePermissionsRequest: UpdateDevicePermissionsRequest + ) = + apiResponseCallback( + retrofitService().submitPermission(callingModule, updateDevicePermissionsRequest) + ) +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/CustomClickConfig.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/CustomClickConfig.kt new file mode 100644 index 0000000000..f6d3b6f68f --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/CustomClickConfig.kt @@ -0,0 +1,15 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +import com.google.gson.annotations.SerializedName + +data class CustomClickConfig( + @SerializedName("type") val type: String? = null, + @SerializedName("eventName") val eventName: String? = null +) diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/HeaderTitleWidgetConfig.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/HeaderTitleWidgetConfig.kt new file mode 100644 index 0000000000..faff2f4678 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/HeaderTitleWidgetConfig.kt @@ -0,0 +1,19 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +import com.google.gson.annotations.SerializedName + +data class HeaderTitleWidgetConfig( + @SerializedName("body") val widgetBody: HeaderTitleBody? = null +) : WidgetConfig() + +data class HeaderTitleBody( + @SerializedName("title") val title: String? = null, + @SerializedName("description") val description: String? = null +) diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/ImportantNote.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/ImportantNote.kt new file mode 100644 index 0000000000..19c55f379c --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/ImportantNote.kt @@ -0,0 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +data class ImportantNote(val title: String?, val subTitle: String?) diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/KycUiStatusValue.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/KycUiStatusValue.kt new file mode 100644 index 0000000000..23c0798977 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/KycUiStatusValue.kt @@ -0,0 +1,18 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +enum class KycUiStatusValue { + PENDING, + COMPLETE, + SOFT_REJECT, + IN_REVIEW, + OSV_VERIFICATION, + OSV_VERIFICATION_IN_PROGRESS, + OSV_OPS_VERIFICATION_PENDING +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/WidgetGenericResponse.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/WidgetGenericResponse.kt new file mode 100644 index 0000000000..8eaf649c5f --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/models/WidgetGenericResponse.kt @@ -0,0 +1,20 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.models + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.widgets.textdisplay.Margin + +abstract class WidgetConfig( + @SerializedName("type") open val widgetType: String? = null, + @SerializedName("id") val widgetId: String? = null, + @SerializedName("status") val status: String? = null, + @SerializedName("widgetLayoutParams") val widgetLayoutParams: WidgetConfigLayoutParams? = null +) + +data class WidgetConfigLayoutParams(@SerializedName("margin") val margin: Margin? = null) diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/activity/VKYCActivity.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/activity/VKYCActivity.kt new file mode 100644 index 0000000000..be614cf72c --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/activity/VKYCActivity.kt @@ -0,0 +1,142 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.activity + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.navi.common.model.ModuleNameV2 +import com.navi.common.ui.activity.BaseActivity +import com.navi.common.utils.observeNullable +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.common.Constants +import com.navi.navi_vkyc.common.VkycScreens +import com.navi.navi_vkyc.presentation.fragments.VKYCMeetingRoomFragment +import com.navi.navi_vkyc.presentation.fragments.VKYCPermissionFragment +import com.navi.navi_vkyc.presentation.fragments.VKYCWaitingForExecutiveFragment +import com.navi.navi_vkyc.presentation.fragments.VkycExitConfirmationBottomSheet +import com.navi.navi_vkyc.presentation.fragments.VkycExitConfirmationBottomSheetCallback +import com.navi.navi_vkyc.presentation.fragments.VkycStatusCheckFragment +import com.navi.navi_vkyc.presentation.viewmodel.VKYCViewModel +import com.navi.navi_vkyc.util.VkycNaviAnalytics +import com.navi.navi_vkyc.util.VkycNaviAnalytics.Companion.VKYC_SCREEN +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class VKYCActivity : BaseActivity(), VkycExitConfirmationBottomSheetCallback { + private lateinit var vkycViewModel: VKYCViewModel + private val naviAnalyticsEventTracker = VkycNaviAnalytics.naviAnalytics.AgentWaitingScreen() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.vkyc_activity) + vkycViewModel = ViewModelProvider(this).get(VKYCViewModel::class.java) + initUI() + initObservers() + } + + private fun initUI() { + navigateToScreen(VkycScreens.VKYC_PERMISSIONS_SCREEN) + } + + private fun initObservers() { + vkycViewModel.cancelVkycResponse.observeNullable(this) { + hideLoader() + finish() + } + } + + // needs to be public to be called from other fragments + public fun navigateToScreen(fragmentName: VkycScreens, extras: Bundle? = null) { + val bundleToBeSent = Bundle() + if (intent.extras != null) bundleToBeSent.putAll(intent.extras) + if (extras != null) bundleToBeSent.putAll(extras) + supportFragmentManager.beginTransaction().apply { + replace(R.id.container, getFragmentInstance(fragmentName, bundleToBeSent)) + addToBackStack(getFragmentTag(fragmentName)) + commit() + } + } + + private fun getFragmentTag(fragmentName: VkycScreens): String { + return when (fragmentName) { + VkycScreens.VKYC_PERMISSIONS_SCREEN -> VKYCPermissionFragment.TAG + VkycScreens.VKYC_WAITING_FOR_EXECUTIVE_SCREEN -> VKYCWaitingForExecutiveFragment.TAG + VkycScreens.VKYC_MEETING_ROOM -> VKYCMeetingRoomFragment.TAG + VkycScreens.VKYC_STATUS_CHECK_SCREEN -> VkycStatusCheckFragment.TAG + } + } + + private fun getFragmentInstance(fragmentName: VkycScreens, extras: Bundle?): Fragment { + return when (fragmentName) { + VkycScreens.VKYC_PERMISSIONS_SCREEN -> VKYCPermissionFragment.getInstance(extras) + VkycScreens.VKYC_WAITING_FOR_EXECUTIVE_SCREEN -> + VKYCWaitingForExecutiveFragment.getInstance(extras) + VkycScreens.VKYC_MEETING_ROOM -> VKYCMeetingRoomFragment.getInstance(extras) + VkycScreens.VKYC_STATUS_CHECK_SCREEN -> VkycStatusCheckFragment.getInstance(extras) + } + } + + override val screenName: String + get() = VKYC_SCREEN + override val moduleName: ModuleNameV2 + get() = ModuleNameV2.COMMON + + override fun onBackPressed() { + if ( + supportFragmentManager.fragments.last() is VKYCPermissionFragment || + supportFragmentManager.fragments.last() is VkycStatusCheckFragment + ) { + finish() + } else { + if (supportFragmentManager.fragments.last() is VKYCWaitingForExecutiveFragment) { + naviAnalyticsEventTracker.onBackClicked( + vkycViewModel.vkycSettingsResponse.value?.kycSourceReferenceId + ) + } + + val vkycExitConfirmationBottomSheet = VkycExitConfirmationBottomSheet.newInstance(this) + safelyShowBottomSheet( + vkycExitConfirmationBottomSheet, + VkycExitConfirmationBottomSheet.TAG + ) + } + } + + override fun onConfirmExit() { + showLoader() + if (supportFragmentManager.fragments.isNotEmpty()) { + val fragment = supportFragmentManager.fragments.last() + if (fragment != null && fragment is VKYCMeetingRoomFragment) { + fragment.leaveRoom() + } + } + vkycViewModel.cancelVkyc(intent?.getStringExtra(Constants.MODULE_NAME) ?: "") + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (supportFragmentManager.fragments.last() is VKYCPermissionFragment) { + val fragment = supportFragmentManager.fragments.last() as VKYCPermissionFragment + fragment.onResultOfRequestPermissions(requestCode, permissions, grantResults) + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (supportFragmentManager.fragments.last() is VKYCPermissionFragment) { + val fragment = supportFragmentManager.fragments.last() as VKYCPermissionFragment + fragment.onFragmentActivityResult(requestCode, resultCode, data) + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/adapter/PermissionAdapter.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/adapter/PermissionAdapter.kt new file mode 100644 index 0000000000..c6b8a3bd3d --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/adapter/PermissionAdapter.kt @@ -0,0 +1,79 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.adapter + +import android.annotation.SuppressLint +import android.content.pm.PackageManager +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.navi.common.model.permission.PermissionTile +import com.navi.common.utils.setShakeAnimation +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycPermissionTypeLayoutBinding + +class PermissionAdapter : RecyclerView.Adapter() { + private val permissionTiles = mutableListOf() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder { + val inflater = LayoutInflater.from(parent.context) + val binding = VkycPermissionTypeLayoutBinding.inflate(inflater, parent, false) + return PermissionViewHolder(binding) + } + + override fun getItemCount() = permissionTiles.size + + override fun onBindViewHolder(holder: PermissionViewHolder, position: Int) { + // if (!isValidIndex(position, itemCount)) return + val permissionTile: PermissionTile = + getPermissionStates(permissionTiles[position], holder.binding) + holder.binding.binder = permissionTile + } + + private fun getPermissionStates( + permissionTile: PermissionTile, + binding: VkycPermissionTypeLayoutBinding + ): PermissionTile { + when (permissionTile.permissionState) { + PackageManager.PERMISSION_DENIED -> { + permissionTile.allowed = false + permissionTile.statusVisibility = true + setShakeAnimation(binding.iconHolderCl) + setShakeAnimation(binding.titleTv) + + binding.titleTv.setTextColor( + ContextCompat.getColor(binding.titleTv.context, R.color.red) + ) + } + PackageManager.PERMISSION_GRANTED -> { + permissionTile.allowed = true + permissionTile.statusVisibility = true + binding.titleTv.setTextColor( + ContextCompat.getColor(binding.titleTv.context, R.color.red) + ) + } + else -> { + permissionTile.allowed = true + permissionTile.statusVisibility = false + } + } + + return permissionTile + } + + @SuppressLint("NotifyDataSetChanged") + fun updatePermissionTiles(permissionTiles: List) { + this.permissionTiles.clear() + this.permissionTiles.addAll(permissionTiles) + notifyDataSetChanged() + } + + class PermissionViewHolder(val binding: VkycPermissionTypeLayoutBinding) : + RecyclerView.ViewHolder(binding.root) +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCMeetingRoomFragment.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCMeetingRoomFragment.kt new file mode 100644 index 0000000000..37564ff42d --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCMeetingRoomFragment.kt @@ -0,0 +1,240 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import com.navi.base.model.CtaData +import com.navi.common.ui.fragment.BaseFragment +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.common.Constants.LATITUDE +import com.navi.navi_vkyc.common.Constants.LONGITUDE +import com.navi.navi_vkyc.common.VkycScreens +import com.navi.navi_vkyc.databinding.VkycMeetingRoomFragmentBinding +import com.navi.navi_vkyc.presentation.activity.VKYCActivity +import com.navi.navi_vkyc.presentation.view.NaviHeaderView +import com.navi.navi_vkyc.presentation.viewmodel.VKYCViewModel +import com.navi.navi_vkyc.util.VkycNaviAnalytics +import dagger.hilt.android.AndroidEntryPoint +import java.text.SimpleDateFormat +import java.util.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import live.hms.video.error.HMSException +import live.hms.video.media.tracks.HMSTrack +import live.hms.video.sdk.HMSActionResultListener +import live.hms.video.sdk.HMSSDK +import live.hms.video.sdk.HMSUpdateListener +import live.hms.video.sdk.models.* +import live.hms.video.sdk.models.enums.HMSPeerUpdate +import live.hms.video.sdk.models.enums.HMSRoomUpdate +import live.hms.video.sdk.models.enums.HMSTrackUpdate +import live.hms.video.sdk.models.trackchangerequest.HMSChangeTrackStateRequest +import live.hms.video.utils.SharedEglContext +import org.webrtc.RendererCommon +import timber.log.Timber + +@AndroidEntryPoint +class VKYCMeetingRoomFragment : BaseFragment(), NaviHeaderView.InteractionListener { + override val screenName: String + get() = VkycNaviAnalytics.VKYC_MEETING_ROOM_SCREEN + + private val hmsSdk by lazy { HMSSDK.Builder(requireActivity().application).build() } + + var binding: VkycMeetingRoomFragmentBinding? = null + + private var sinkAdded: Boolean = false + + private lateinit var vkycViewModel: VKYCViewModel + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = VkycMeetingRoomFragmentBinding.inflate(inflater, container, false) + return binding?.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + vkycViewModel = ViewModelProvider(requireActivity())[VKYCViewModel::class.java] + setListener() + initError(vkycViewModel, actionErrorV2Enabled = true) + initUi() + initObservers() + } + + private fun initUi() { + binding?.tvLatitude?.text = + String.format(getString(R.string.latitude_1_f), arguments?.getDouble(LATITUDE, 0.0)) + binding?.tvLongitude?.text = + String.format(getString(R.string.longitude_1_f), arguments?.getDouble(LONGITUDE, 0.0)) + try { + val date = Date() + val dateFormatter = SimpleDateFormat("dd/MM/yyyy HH:mm:ss a", Locale.getDefault()) + val time = dateFormatter.format(date) + binding?.tvTime?.text = String.format(getString(R.string.time_1_s), time) + } catch (ex: Exception) { + binding?.tvTime?.visibility = View.GONE + } + } + + private fun initObservers() { + vkycViewModel.vkycSettingsResponse.observe(viewLifecycleOwner) { + it?.settings?.let { settings -> + val config = + HMSConfig(settings.userName ?: String(), settings.authToken ?: String()) + hmsSdk.join(config, hmsListener) + } + } + + vkycViewModel.permissionDetailsResponse.observe(viewLifecycleOwner) { response -> + response?.let { permissionDetailsResponse -> + setProperties( + permissionDetailsResponse.header?.title.orEmpty(), + permissionDetailsResponse.header?.leftIconCode, + permissionDetailsResponse.header?.infoCta, + null, + hideDivider = true, + hideHelp = true + ) + + binding?.headerView?.setOnInteractionListener(this) + } + } + } + + override fun onDestroy() { + super.onDestroy() + leaveRoom() + } + + private fun setListener() { + + binding?.ivSwitchCamera?.setOnClickListener { + hmsSdk + .getLocalPeer() + ?.videoTrack + ?.switchCamera( + object : HMSActionResultListener { + override fun onError(error: HMSException) { + Timber.e(error) + } + + override fun onSuccess() { + Timber.d("Camera Switched") + } + } + ) + } + } + + fun leaveRoom() { + hmsSdk.leave() + } + + companion object { + const val TAG = "VKYCMeetingRoomFragment" + + fun getInstance(bundle: Bundle?): VKYCMeetingRoomFragment { + return VKYCMeetingRoomFragment().apply { arguments = bundle } + } + } + + override fun onPause() { + super.onPause() + hmsSdk.getLocalPeer()?.videoTrack?.setMute(true) + } + + override fun onResume() { + super.onResume() + hmsSdk.getLocalPeer()?.videoTrack?.setMute(false) + // addVideo() + } + + private fun addVideo() { + hmsSdk.getLocalPeer()?.videoTrack?.let { + if (!sinkAdded) { + CoroutineScope(Dispatchers.Main).launch { + binding?.videoSurfaceView?.apply { + setEnableHardwareScaler(true) + setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) + init(SharedEglContext.context, null) + it.addSink(this) + } + sinkAdded = true + } + } + } + } + + override fun setProperties( + title: String, + leftIconCode: String?, + infoCta: CtaData?, + colorInt: Int?, + hideDivider: Boolean, + hideHelp: Boolean + ) { + binding + ?.headerView + ?.setProperties(title, leftIconCode, infoCta, null, hideDivider = true, hideHelp = true) + } + + override fun onHelpButtonPressed() { + // Do Nothing + } + + override fun onBackButtonPressed() { + activity?.onBackPressed() + } + + private val hmsListener by lazy { + object : HMSUpdateListener { + + override fun onChangeTrackStateRequest(details: HMSChangeTrackStateRequest) {} + + override fun onError(error: HMSException) { + Timber.e(error) + if (error.isTerminal) { + (requireActivity() as VKYCActivity).navigateToScreen( + VkycScreens.VKYC_STATUS_CHECK_SCREEN + ) + } + } + + override fun onJoin(room: HMSRoom) { + Timber.d("room Joined ${room.name}") + } + + override fun onMessageReceived(message: HMSMessage) {} + + override fun onPeerUpdate(type: HMSPeerUpdate, peer: HMSPeer) { + addVideo() + } + + override fun onRoleChangeRequest(request: HMSRoleChangeRequest) {} + + override fun onRoomUpdate(type: HMSRoomUpdate, hmsRoom: HMSRoom) {} + + override fun onRemovedFromRoom(notification: HMSRemovedFromRoom) { + super.onRemovedFromRoom(notification) + (requireActivity() as VKYCActivity).navigateToScreen( + VkycScreens.VKYC_STATUS_CHECK_SCREEN + ) + } + + override fun onTrackUpdate(type: HMSTrackUpdate, track: HMSTrack, peer: HMSPeer) {} + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCPermissionFragment.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCPermissionFragment.kt new file mode 100644 index 0000000000..a7b9e6be88 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCPermissionFragment.kt @@ -0,0 +1,394 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import com.navi.base.model.CtaData +import com.navi.base.model.LineItem +import com.navi.base.sharedpref.PreferenceManager +import com.navi.common.decorator.TopMarginItemDecoration +import com.navi.common.deeplink.DeepLinkManager +import com.navi.common.managers.NaviLocationManager +import com.navi.common.managers.PermissionsManager +import com.navi.common.model.permission.PermissionTile +import com.navi.common.ui.fragment.BaseFragment +import com.navi.common.utils.CommonUtils +import com.navi.common.utils.observeNullable +import com.navi.common.utils.setCornerRadius +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.common.VkycScreens +import com.navi.navi_vkyc.databinding.VkycPermissionFragmentBinding +import com.navi.navi_vkyc.models.ImportantNote +import com.navi.navi_vkyc.presentation.activity.VKYCActivity +import com.navi.navi_vkyc.presentation.adapter.PermissionAdapter +import com.navi.navi_vkyc.presentation.view.FooterView +import com.navi.navi_vkyc.presentation.view.NaviHeaderView +import com.navi.navi_vkyc.presentation.viewmodel.VKYCViewModel +import com.navi.navi_vkyc.util.* +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class VKYCPermissionFragment : + BaseFragment(), FooterView.FooterInteractionListener, NaviHeaderView.InteractionListener { + private var binding: VkycPermissionFragmentBinding? = null + + private var permissionsManager: PermissionsManager? = null + private val permissionAdapter by lazy { PermissionAdapter() } + private val naviAnalyticsEventTracker = VkycNaviAnalytics.naviAnalytics.Permission() + private val naviLocationManager = NaviLocationManager() + private lateinit var vkycViewModel: VKYCViewModel + private lateinit var permissionTiles: List + private val requiredPermissions = + arrayOf( + Manifest.permission.RECORD_AUDIO, + Manifest.permission.CAMERA, + Manifest.permission.ACCESS_FINE_LOCATION + ) + + override val screenName: String + get() = VkycNaviAnalytics.VKYC_PERMISSIONS_SCREEN + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = VkycPermissionFragmentBinding.inflate(inflater, container, false) + return binding?.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + vkycViewModel = ViewModelProvider(requireActivity()).get(VKYCViewModel::class.java) + permissionTiles = getPermissionTilesForVKYC(requireActivity().application) + initUi() + initObservers() + initError(vkycViewModel, actionErrorV2Enabled = true) + fetchPermissionDetails() + } + + override fun onDestroyView() { + super.onDestroyView() + binding = null + } + + override fun onAttach(context: Context) { + super.onAttach(context) + permissionsManager = PermissionsManager(context as Activity) + } + + override fun onDetach() { + super.onDetach() + permissionsManager = null + } + + private fun fetchPermissionDetails() { + showLoader() + vkycViewModel.fetchPermissionDetails( + arguments?.getString(com.navi.navi_vkyc.common.Constants.MODULE_NAME) ?: "" + ) + } + + private fun initObservers() { + vkycViewModel.permissionDetailsResponse.observeNullable(this) { response -> + hideLoader() + naviAnalyticsEventTracker.onLandOnPermissionScreen() + response?.let { permissionDetailsResponse -> + setProperties( + permissionDetailsResponse.header?.title.orEmpty(), + permissionDetailsResponse.header?.leftIconCode, + permissionDetailsResponse.header?.infoCta, + null, + hideDivider = true, + hideHelp = false + ) + binding?.headerDescriptionView?.setProperties(permissionDetailsResponse.header) + + binding + ?.footerView + ?.setProperties(permissionDetailsResponse.footer, listener = this) + } + if (permissionsManager?.hasPermissions(requiredPermissions) == true) { + permissionTiles.forEach { permissionTile -> + permissionTile.qualifier?.let { + permissionTile.permissionState = PackageManager.PERMISSION_GRANTED + } + } + permissionAdapter.updatePermissionTiles(permissionTiles) + onGrantPermissions() + } + } + naviLocationManager.locationPollingData.observeNullable(this) { + vkycViewModel.submitPermission( + arguments?.getString(com.navi.navi_vkyc.common.Constants.MODULE_NAME) ?: "" + ) + } + + vkycViewModel.vkycPermissionSubmitResponse.observeNullable(this) { + hideLoader() + val location = CommonUtils.getUserLocation() + location?.let { + naviLocationManager.locationPollingData.removeObservers(this) + if (activity is VKYCActivity) { + (activity as VKYCActivity).navigateToScreen( + VkycScreens.VKYC_WAITING_FOR_EXECUTIVE_SCREEN, + Bundle().apply { + putDouble( + com.navi.navi_vkyc.common.Constants.LATITUDE, + it.latitude?.toDouble() ?: 0.0 + ) + putDouble( + com.navi.navi_vkyc.common.Constants.LONGITUDE, + it.longitude?.toDouble() ?: 0.0 + ) + } + ) + } + } + } + } + + private fun initUi() { + binding?.permissionTileRvv?.layoutManager = LinearLayoutManager(context) + binding?.permissionTileRvv?.adapter = permissionAdapter + binding + ?.permissionTileRvv + ?.addItemDecoration( + TopMarginItemDecoration(resources.getDimension(R.dimen.layout_dp_24)) + ) + + binding + ?.permissionDeniedLayoutV2 + ?.setCornerRadius(resources.getDimension(R.dimen.layout_dp_8)) + permissionAdapter.updatePermissionTiles(permissionTiles) + binding?.permissionDeniedLayoutV2?.setCallback { + naviAnalyticsEventTracker.onAllPermissionMandatoryClicked() + openNativePermissionPage( + arguments?.getString(com.navi.navi_vkyc.common.Constants.APPLICATION_ID), + activity + ) + } + binding?.importantNoteBinder = + ImportantNote( + resources.getString(R.string.vkyc_important_note_title), + resources.getString(R.string.vkyc_important_note_details) + ) + binding?.headerView?.setOnInteractionListener(this) + + binding?.footerView?.showDataSafetyHeader() + binding?.footerView?.binding?.knowMoreTv?.setOnClickListener { + vkycViewModel.permissionDetailsResponse.value?.content?.dataSafetyBottomSheet?.let { + val infoBottomSheet = VkycInformationBottomSheet.getInstance(it) + safelyShowBottomSheet(infoBottomSheet, VkycInformationBottomSheet.TAG) + } + } + } + + private fun onGrantPermissions() { + showLoader() + sendLocation() + } + + private fun sendLocation() { + PreferenceManager.setBooleanPreference(NaviLocationManager.IS_HARD_LOCATION_UPDATE, true) + activity?.let { naviLocationManager.postLocationData(it) } + } + + fun onResultOfRequestPermissions( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + if (requestCode == PermissionsManager.REQUEST_CODE) { + sendAnalyticsEventFroPermission(permissions, grantResults) + if (permissionsManager?.hasPermissions(requiredPermissions) ?: false) { + permissionTiles.forEach { permissionTile -> + permissionTile.qualifier?.let { + permissionTile.permissionState = PackageManager.PERMISSION_GRANTED + } + } + permissionAdapter.updatePermissionTiles(permissionTiles) + return onGrantPermissions() + } + checkPermissionResult(permissions, grantResults) + permissionAdapter.updatePermissionTiles(permissionTiles) + activity?.let { fragmentActivity -> + permissionTiles.forEach { permissionTile -> + permissionTile.qualifier?.forEach { qualifier -> + val index = permissions.indexOf(qualifier) + + takeIf { index != -1 && index < grantResults.count() } + ?.let { + when (permissions.getOrNull(index)) { + Manifest.permission.ACCESS_FINE_LOCATION -> { + if ( + !hasPermissions( + fragmentActivity, + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION) + ) && + isDontAskAgainClicked( + fragmentActivity, + Manifest.permission.ACCESS_FINE_LOCATION, + grantResults[index] + ) + ) { + naviAnalyticsEventTracker + .onLocationDeniedAndDontAskClicked() + } + } + } + } + } + } + } + } + } + + private fun isDontAskAgainClicked( + activity: Activity, + permission: String, + grantResult: Int + ): Boolean { + return !ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) && + grantResult == PackageManager.PERMISSION_DENIED + } + + private fun checkPermissionResult(permissions: Array, grantResults: IntArray) { + activity?.let { fragmentActivity -> + permissionTiles.forEach { permissionTile -> + permissionTile.qualifier?.forEach { qualifier -> + val index = permissions.indexOf(qualifier) + if (index != -1 && index < grantResults.count()) { + permissionTile.permissionState = grantResults[index] + if ( + isDontAskAgainClicked( + fragmentActivity, + permissions[index], + grantResults[index] + ) + ) { + binding?.permissionDeniedLayoutV2?.visibility = View.VISIBLE + } + } else permissionTile.permissionState = PackageManager.PERMISSION_GRANTED + } + } + } + } + + private fun sendAnalyticsEventFroPermission( + permissions: Array, + grantResults: IntArray + ) { + permissions.forEachIndexed { index, permission -> + if (grantResults[index] == PackageManager.PERMISSION_GRANTED) { + when (permission) { + Manifest.permission.CAMERA -> + naviAnalyticsEventTracker.onCameraPermissionAllow() + Manifest.permission.RECORD_AUDIO -> + naviAnalyticsEventTracker.onMicrophonePermissionAllow() + Manifest.permission.ACCESS_FINE_LOCATION -> + naviAnalyticsEventTracker.onLocationPermissionAllow() + } + } else { + when (permission) { + Manifest.permission.READ_SMS -> + naviAnalyticsEventTracker.onCameraPermissionDenied() + Manifest.permission.RECORD_AUDIO -> + naviAnalyticsEventTracker.onMicrophonePermissionDenied() + Manifest.permission.ACCESS_FINE_LOCATION -> + naviAnalyticsEventTracker.onLocationPermissionDenied() + } + } + } + } + + override fun setProperties( + title: String, + leftIconCode: String?, + infoCta: CtaData?, + colorInt: Int?, + hideDivider: Boolean, + hideHelp: Boolean + ) { + binding?.headerView?.setProperties(title, leftIconCode, infoCta) + } + + override fun onHelpButtonPressed() { + activity?.let { + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity = it, + ctaData = + CtaData( + url = "CUSTOMER_SUPPORT", + parameters = listOf(LineItem("screen", screenName)) + ), + finish = false, + clearTask = false, + bundle = null + ) + } + } + + override fun onBackButtonPressed() { + activity?.finish() + } + + override fun onFooterBackPressed(backCta: CtaData?) { + activity?.finish() + } + + override fun onFooterNextPressed(nextCta: CtaData?) { + naviAnalyticsEventTracker.onPermissionContinueClicked() + if (binding?.permissionDeniedLayoutV2?.visibility == View.VISIBLE) { + openNativePermissionPage( + arguments?.getString(com.navi.navi_vkyc.common.Constants.APPLICATION_ID), + activity + ) + } else { + permissionsManager?.requestPermissions(requiredPermissions) + } + } + + fun onFragmentActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + when (requestCode) { + NaviLocationManager.REQUEST_LOCATION_SETTINGS -> { + naviAnalyticsEventTracker.onGPSPopupClicked( + if (resultCode == AppCompatActivity.RESULT_OK) { + OK + } else { + NO + } + ) + hideLoader() + } + } + } + + companion object { + const val TAG = "VKYCPermissionFragment" + const val OK = "Ok" + const val NO = "No" + + fun getInstance(bundle: Bundle?): VKYCPermissionFragment { + return VKYCPermissionFragment().apply { arguments = bundle } + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCWaitingForExecutiveFragment.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCWaitingForExecutiveFragment.kt new file mode 100644 index 0000000000..f8d5722c5d --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VKYCWaitingForExecutiveFragment.kt @@ -0,0 +1,218 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.get +import com.navi.base.model.CtaData +import com.navi.base.model.LineItem +import com.navi.common.deeplink.DeepLinkManager +import com.navi.common.ui.fragment.BaseFragment +import com.navi.common.utils.ApiPollScheduler +import com.navi.common.utils.observeNullable +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.common.VkycScreens +import com.navi.navi_vkyc.databinding.VkycWaitingForExecutiveBinding +import com.navi.navi_vkyc.models.ImportantNote +import com.navi.navi_vkyc.presentation.activity.VKYCActivity +import com.navi.navi_vkyc.presentation.view.NaviHeaderView +import com.navi.navi_vkyc.presentation.viewmodel.VKYCViewModel +import com.navi.navi_vkyc.util.API_ERROR_CONSTNATS +import com.navi.navi_vkyc.util.VkycNaviAnalytics +import com.navi.navi_vkyc.util.goToKYCPage +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class VKYCWaitingForExecutiveFragment : BaseFragment(), NaviHeaderView.InteractionListener { + override val screenName: String + get() = VkycNaviAnalytics.VKYC_WAITING_FOR_EXECUTIVE_SCREEN + private var binding: VkycWaitingForExecutiveBinding? = null + private lateinit var vkycViewModel: VKYCViewModel + + private var vkycAgentAssignedApiPollScheduler: ApiPollScheduler? = null + private val vkycAgentAssignmentSuccessStates = listOf("AGENT_JOINED") + private val vkycAgentAssignmentFailureStates = listOf("ERROR", "FAILED_TO_FIND_AGENT") + private val naviAnalyticsEventTracker = VkycNaviAnalytics.naviAnalytics.AgentWaitingScreen() + private var startTime: Long = 0 + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = VkycWaitingForExecutiveBinding.inflate(inflater, container, false) + return binding!!.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + vkycViewModel = ViewModelProvider(requireActivity()).get(VKYCViewModel::class.java) + initUi() + initObservers() + naviAnalyticsEventTracker.onWaitingForAgentScreenShown() + fetchVkycSettings() + + initError( + vkycViewModel, + listOf( + Pair(vkycSettingsOnClickListener, API_ERROR_CONSTNATS.VKYC_SETTINGS), + ), + actionErrorV2Enabled = true + ) + } + + private val vkycSettingsOnClickListener: View.OnClickListener = + View.OnClickListener { fetchVkycSettings() } + + override fun onDestroyView() { + super.onDestroyView() + binding = null + } + + override fun onDestroy() { + super.onDestroy() + vkycAgentAssignedApiPollScheduler?.stopApiPoll() + } + + private fun initUi() { + binding?.headerView?.setOnInteractionListener(this) + binding?.importantNoteBinder = + ImportantNote( + resources.getString(R.string.vkyc_important_note_title), + resources.getString(R.string.vkyc_please_dont_leave) + ) + } + + private fun fetchVkycSettings() { + showLoader() + vkycViewModel.fetchVkycSettings( + arguments?.getString(com.navi.navi_vkyc.common.Constants.MODULE_NAME) ?: "", + arguments?.getDouble(com.navi.navi_vkyc.common.Constants.LATITUDE) ?: 0.0, + arguments?.getDouble(com.navi.navi_vkyc.common.Constants.LONGITUDE) ?: 0.0 + ) + } + + private fun initObservers() { + vkycViewModel.waitingPageDetailsResponse.observeNullable(this) { response -> + hideLoader() + response?.let { waitingPageDetailsResponse -> + setProperties( + waitingPageDetailsResponse.header?.title.orEmpty(), + waitingPageDetailsResponse.header?.leftIconCode, + waitingPageDetailsResponse.header?.infoCta, + null, + hideDivider = true, + hideHelp = false + ) + } + + startTime = System.currentTimeMillis() + onPageResponseReceived() + } + + vkycViewModel.vkycSettingsResponse.observeNullable(this) { response -> + response?.let { + vkycViewModel.fetchWaitingPageDetails( + arguments?.getString(com.navi.navi_vkyc.common.Constants.MODULE_NAME) ?: "" + ) + } + } + + vkycViewModel.vkycAgentAssignedStatusResponse.observeNullable(this) { response -> + response?.let { + if (vkycAgentAssignmentSuccessStates.contains(it.status)) { + val endTime = System.currentTimeMillis() + val timeDiff = (endTime - startTime) / 1000 + naviAnalyticsEventTracker.onVKycCallConnected( + timeDiff, + vkycViewModel.vkycSettingsResponse.value?.kycSourceReferenceId + ) + vkycAgentAssignedApiPollScheduler?.stopApiPoll() + (requireActivity() as VKYCActivity).navigateToScreen( + VkycScreens.VKYC_MEETING_ROOM, + arguments + ) + } else if (vkycAgentAssignmentFailureStates.contains(it.status)) { + vkycAgentAssignedApiPollScheduler?.stopApiPoll() + goToKYCPage(activity) + } + } + } + } + + private fun onPageResponseReceived() { + vkycAgentAssignedApiPollScheduler = + ApiPollScheduler(doOnTimeout = onTimeout) { + vkycViewModel.fetchVkycAgentAssignedStatus( + arguments?.getString(com.navi.navi_vkyc.common.Constants.MODULE_NAME) ?: "" + ) + } + vkycAgentAssignedApiPollScheduler?.scheduleApiPoll() + } + + private val errorTag: String? = null + private val onTimeout = { handleTimeOutError(errorTag.orEmpty()) } + + private fun handleTimeOutError(errorTag: String) { + showTimeoutErrorScreen( + null, + apiPollScheduler = vkycAgentAssignedApiPollScheduler, + pollingTimeoutClickListener, + errorTag + ) + } + + private val pollingTimeoutClickListener: View.OnClickListener = + View.OnClickListener { onPageResponseReceived() } + + companion object { + const val TAG = "VKYCWaitingForExecutiveFragment" + + fun getInstance(bundle: Bundle?): VKYCWaitingForExecutiveFragment { + return VKYCWaitingForExecutiveFragment().apply { arguments = bundle } + } + } + + override fun setProperties( + title: String, + leftIconCode: String?, + infoCta: CtaData?, + colorInt: Int?, + hideDivider: Boolean, + hideHelp: Boolean + ) { + binding + ?.headerView + ?.setProperties(title, leftIconCode, infoCta, colorInt, hideDivider, hideHelp) + } + + override fun onHelpButtonPressed() { + activity?.let { + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity = it, + ctaData = + CtaData( + url = "CUSTOMER_SUPPORT", + parameters = listOf(LineItem("screen", screenName)) + ), + finish = false, + clearTask = false, + bundle = null + ) + } + } + + override fun onBackButtonPressed() { + activity?.onBackPressed() + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycExitConfirmationBottomSheet.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycExitConfirmationBottomSheet.kt new file mode 100644 index 0000000000..b31961da1d --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycExitConfirmationBottomSheet.kt @@ -0,0 +1,51 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.view.ViewStub +import androidx.databinding.DataBindingUtil +import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycExitConfirmationBinding + +interface VkycExitConfirmationBottomSheetCallback { + fun onConfirmExit() +} + +class VkycExitConfirmationBottomSheet : BaseBottomSheet() { + private lateinit var callback: VkycExitConfirmationBottomSheetCallback + private var binding: VkycExitConfirmationBinding? = null + + override fun setContainerView(viewStub: ViewStub) { + viewStub.layoutResource = R.layout.vkyc_exit_confirmation + binding = DataBindingUtil.getBinding(viewStub.inflate())!! + binding?.positiveButton?.transformationMethod = null + binding?.positiveButton?.setOnClickListener { + callback.onConfirmExit() + dismiss() + } + + binding?.negativeButton?.setOnClickListener { dismiss() } + binding?.negativeButton?.transformationMethod = null + } + + override val screenName: String + get() = "VkycExitConfirmationBottomSheet" + + companion object { + val TAG: String = "VkycExitConfirmationBottomSheet" + + fun newInstance( + callback: VkycExitConfirmationBottomSheetCallback + ): VkycExitConfirmationBottomSheet { + val fragment = VkycExitConfirmationBottomSheet() + fragment.callback = callback + return fragment + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycInformationBottomSheet.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycInformationBottomSheet.kt new file mode 100644 index 0000000000..d42b8161ed --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycInformationBottomSheet.kt @@ -0,0 +1,65 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.os.Bundle +import android.view.ViewStub +import androidx.databinding.DataBindingUtil +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.navi.base.model.CtaData +import com.navi.common.model.vkyc.InfoBottomSheetConfig +import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycInfoBottomSheetLayoutBinding + +class VkycInformationBottomSheet : BaseBottomSheet() { + + private lateinit var binding: VkycInfoBottomSheetLayoutBinding + private val _cta = MutableLiveData() + val cta: LiveData + get() = _cta + + override fun setContainerView(viewStub: ViewStub) { + viewStub.layoutResource = R.layout.vkyc_info_bottom_sheet_layout + binding = DataBindingUtil.getBinding(viewStub.inflate())!! + initData() + initUI() + } + + private fun initUI() { + binding.primaryAbv.setOnClickListener { + safelyDismissDialog() + _cta.value = binding.binder?.cta + } + } + + private fun initData() { + arguments?.getParcelable(KEY_DATA)?.let { + binding.binder = it + binding.primaryAbv.setProperties( + binding.binder?.cta?.title, + R.color.white, + R.color.outrageous_orange + ) + } + } + + override val screenName: String + get() = TAG + + companion object { + private const val KEY_DATA = "KEY_DATA" + const val TAG = "INFORMATION_BOTTOMSHEET" + fun getInstance(infoBottomSheetConfig: InfoBottomSheetConfig): VkycInformationBottomSheet { + return VkycInformationBottomSheet().apply { + arguments = Bundle().apply { putParcelable(KEY_DATA, infoBottomSheetConfig) } + } + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycStatusCheckFragment.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycStatusCheckFragment.kt new file mode 100644 index 0000000000..65c98c43e7 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/fragments/VkycStatusCheckFragment.kt @@ -0,0 +1,133 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import com.navi.common.ui.fragment.BaseFragment +import com.navi.common.utils.ApiPollScheduler +import com.navi.common.utils.observeNullable +import com.navi.common.utils.orTrue +import com.navi.navi_vkyc.common.Constants +import com.navi.navi_vkyc.databinding.VkycStatusCheckFragmentBinding +import com.navi.navi_vkyc.presentation.viewmodel.VKYCViewModel +import com.navi.navi_vkyc.util.VkycNaviAnalytics +import com.navi.navi_vkyc.util.goToKYCPage +import com.navi.navi_vkyc.util.goToSoftRejectPage +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class VkycStatusCheckFragment : BaseFragment() { + override val screenName: String + get() = VkycNaviAnalytics.VKYC_STATUS_CHECK_SCREEN + private lateinit var vkycViewModel: VKYCViewModel + private var vkycStatusApiPollScheduler: ApiPollScheduler? = null + private val vkycSuccessStates = + listOf( + "VKYC_APPROVED", + "VKYC_MANUAL_AUDIT_APPROVED", + "VKYC_AUTO_AUDIT_SUCCESS", + "VKYC_MANUAL_AUDIT_REQUESTED", + "VKYC_AUDIT_PENDING" + ) + private val vkycFailureStates = + listOf( + "VKYC_INCOMPLETE", + "VKYC_REJECTED", + "VKYC_MANUAL_AUDIT_REJECTED", + "VKYC_MANUAL_AUDIT_INCOMPLETE", + "VKYC_AUTO_AUDIT_FAILED" + ) + private val naviAnalyticsEventTracker = VkycNaviAnalytics.naviAnalytics.VerdictScreen() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return VkycStatusCheckFragmentBinding.inflate(inflater, container, false).root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + vkycViewModel = ViewModelProvider(requireActivity()).get(VKYCViewModel::class.java) + initObservers() + fetchVkycStatus() + initError(vkycViewModel, actionErrorV2Enabled = true) + naviAnalyticsEventTracker.landedOnVerdictScreen( + vkycViewModel.vkycSettingsResponse.value?.kycSourceReferenceId + ) + } + + private fun fetchVkycStatus() { + vkycStatusApiPollScheduler = + ApiPollScheduler(doOnTimeout = onTimeout) { + vkycViewModel.fetchVkycStatus(arguments?.getString(Constants.MODULE_NAME) ?: "") + } + vkycStatusApiPollScheduler?.scheduleApiPoll() + } + + override fun onDestroy() { + super.onDestroy() + vkycStatusApiPollScheduler?.stopApiPoll() + } + + private fun initObservers() { + vkycViewModel.vkycStatusResponse.observeNullable(this) { response -> + response?.let { + if ( + vkycSuccessStates.contains(it.status) || vkycFailureStates.contains(it.status) + ) { + vkycStatusApiPollScheduler?.stopApiPoll() + if (it.status == "VKYC_REJECTED" || it.status == "VKYC_MANUAL_AUDIT_REJECTED") { + vkycViewModel.fetchKycStatus( + callingModule = arguments?.getString(Constants.MODULE_NAME) ?: "" + ) + } else { + goToKYCPage(activity) + } + } + } + } + observeKycStatus() + } + + private fun observeKycStatus() { + vkycViewModel.kycStatus.observeNullable(this) { + if (it?.softReject?.not().orTrue() || activity?.isDestroyed.orTrue()) + goToKYCPage(requireActivity()) + goToSoftRejectPage(requireActivity()) + } + } + + private val errorTag: String? = null + private val onTimeout = { handleTimeOutError(errorTag.orEmpty()) } + + private fun handleTimeOutError(errorTag: String) { + showTimeoutErrorScreen( + null, + apiPollScheduler = vkycStatusApiPollScheduler, + pollingTimeoutClickListener, + errorTag + ) + } + + private val pollingTimeoutClickListener: View.OnClickListener = + View.OnClickListener { fetchVkycStatus() } + + companion object { + const val TAG = "VkycStatusCheckFragment" + + fun getInstance(bundle: Bundle?): VkycStatusCheckFragment { + return VkycStatusCheckFragment().apply { arguments = bundle } + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/FooterView.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/FooterView.kt new file mode 100644 index 0000000000..5e5bd95d49 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/FooterView.kt @@ -0,0 +1,115 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.LinearLayout +import androidx.core.content.res.ResourcesCompat +import com.navi.base.model.CtaData +import com.navi.base.utils.underLineText +import com.navi.common.model.StyledTextWithIconCode +import com.navi.common.utils.spannableString +import com.navi.design.utils.getNaviDrawable +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycFooterViewBinding +import com.navi.navi_vkyc.models.CustomClickConfig +import com.navi.navi_vkyc.models.Footer + +// import com.naviapp.utils.setOnCustomClickListener + +class FooterView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) : + LinearLayout(context, attrs) { + + private var listener: FooterInteractionListener? = null + + val binding = VkycFooterViewBinding.inflate(LayoutInflater.from(context), this, true) + + init { + defaultInitButtons() + } + + fun setInteractionListener( + listener: FooterInteractionListener, + backCta: CtaData? = null, + nextCta: CtaData? = null, + customClickConfig: CustomClickConfig? = null + ) { + this.listener = listener + initListener(customClickConfig, backCta, nextCta) + } + + private fun initListener( + customClickConfig: CustomClickConfig?, + backCta: CtaData?, + nextCta: CtaData? + ) { + binding.prevBtn.setOnClickListener { listener?.onFooterBackPressed(backCta) } + binding.nextBtn.setOnClickListener { listener?.onFooterNextPressed(nextCta) } + // binding.nextBtn.setOnCustomClickListener({ + // listener?.onFooterNextPressed(nextCta) + // }, customClickConfig) + } + + private fun defaultInitButtons() { + binding.prevBtn.background = + getNaviDrawable( + backgroundColor = + ResourcesCompat.getColor(resources, R.color.view_background_color_six, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_100).toInt() + ) + + binding.nextBtn.background = + getNaviDrawable( + backgroundColor = + ResourcesCompat.getColor(resources, R.color.outrageous_orange, null), + cornerRadius = resources.getDimension(R.dimen.layout_dp_100).toInt() + ) + binding.knowMoreTv.underLineText() + } + + fun setProperties( + footer: Footer?, + listener: FooterInteractionListener? = null, + customClickConfig: CustomClickConfig? = null + ) { + footer?.let { binding.footer = it } + listener?.let { + setInteractionListener(listener, footer?.backCta, footer?.nextCta, customClickConfig) + } + } + + fun showDataSafetyHeader(showKnowMore: Boolean = true) { + binding.dataSafetyG.visibility = View.VISIBLE + if (!showKnowMore) { + binding.knowMoreTv.visibility = View.GONE + } + } + + fun setCheckboxText(text: StyledTextWithIconCode?, checked: Boolean = false) { + binding.checkboxLl.visibility = View.VISIBLE + binding.checkboxCb.isChecked = checked + text?.let { binding.checkboxTv.spannableString(text) } + } + + fun hideCheckboxText() { + binding.checkboxLl.visibility = View.GONE + } + + fun setNextButtonEnable(enabled: Boolean) { + binding.nextBtn.isEnabled = enabled + binding.nextBtn.alpha = if (enabled) 1f else 0.56f + } + + interface FooterInteractionListener { + fun onFooterBackPressed(backCta: CtaData?) + fun onFooterNextPressed(nextCta: CtaData?) + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/HeaderDescriptionView.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/HeaderDescriptionView.kt new file mode 100644 index 0000000000..b14472fba8 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/HeaderDescriptionView.kt @@ -0,0 +1,60 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.design.utils.dpToPxInInt +import com.navi.navi_vkyc.databinding.VkycHeaderWithDescriptionViewBinding +import com.navi.navi_vkyc.models.Header +import com.navi.navi_vkyc.models.HeaderTitleWidgetConfig + +class HeaderDescriptionView +@JvmOverloads +constructor(context: Context, attr: AttributeSet? = null) : ConstraintLayout(context, attr) { + + private val binding: VkycHeaderWithDescriptionViewBinding + + init { + binding = + VkycHeaderWithDescriptionViewBinding.inflate(LayoutInflater.from(context), this, true) + layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) + } + + fun setProperties(header: Header?) { + header?.let { binding.header = it } + } + + fun setProperties(widgetConfig: HeaderTitleWidgetConfig?) { + widgetConfig?.widgetLayoutParams?.let { + it.margin?.let { + (this.layoutParams as ViewGroup.MarginLayoutParams).setMargins( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + } + widgetConfig?.widgetBody?.let { + binding.header = Header(subtitle = it.title, description = it.description) + } + } + + fun hideHeader() { + binding.root.visibility = View.GONE + } + + fun showHeader() { + binding.root.visibility = View.VISIBLE + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/NaviHeaderView.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/NaviHeaderView.kt new file mode 100644 index 0000000000..cdabdf6af3 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/NaviHeaderView.kt @@ -0,0 +1,128 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.view +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import androidx.core.view.isVisible +import com.navi.base.model.CtaData +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycNaviHeaderViewBinding +import com.navi.naviwidgets.utils.NaviWidgetIconUtils + +class NaviHeaderView(context: Context, attrs: AttributeSet? = null) : + ConstraintLayout(context, attrs), View.OnClickListener { + + private var listener: InteractionListener? = null + private val binding = + VkycNaviHeaderViewBinding.inflate(LayoutInflater.from(context), this, true) + + fun setOnClickListener(listener: InteractionListener) { + this.listener = listener + } + + fun setOnInteractionListener(listener: InteractionListener) { + this.listener = listener + initListener() + } + + fun hideDivider() { + binding.divider.visibility = View.GONE + } + + fun showDivider() { + binding.divider.visibility = View.VISIBLE + } + + fun setHeaderBackgroundColor(colorId: Int) { + binding.naviHeaderCl.setBackgroundColor(ResourcesCompat.getColor(resources, colorId, null)) + } + + fun setProperties( + title: String, + leftIconCode: String?, + infoCta: CtaData?, + colorInt: Int? = null, + hideDivider: Boolean = true, + hideHelp: Boolean = false + ) { + binding.titleTv.text = title + leftIconCode?.let { NaviWidgetIconUtils.updateIcon(it, binding.leftIcon) } + infoCta?.let { binding.rightIcon.text = it.title } + + colorInt?.let { + binding.naviHeaderCl.setBackgroundColor(ContextCompat.getColor(context, colorInt)) + } + + if (hideDivider) { + hideDivider() + } else { + showDivider() + } + + if (hideHelp) { + hideHelp() + } + } + + fun initListener() { + binding.leftIcon.setOnClickListener(this) + binding.rightIcon.setOnClickListener(this) + } + + fun removeDivider() { + binding.divider.isVisible = false + } + + fun handleHelpButton(enableHelp: Boolean?) { + if (enableHelp == true) { + binding.rightIcon.visibility = VISIBLE + } else { + binding.rightIcon.visibility = INVISIBLE + } + } + + override fun onClick(view: View?) { + when (view?.id) { + R.id.left_icon -> { + listener?.onBackButtonPressed() + } + R.id.right_icon -> { + listener?.onHelpButtonPressed() + } + } + } + + fun hideHelp() { + binding.rightIcon.visibility = View.GONE + } + + interface InteractionListener { + fun setProperties( + title: String, + leftIconCode: String?, + infoCta: CtaData?, + colorInt: Int? = null, + hideDivider: Boolean = true, + hideHelp: Boolean = false + ) + fun onHelpButtonPressed() + fun onBackButtonPressed() + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/PermissionDeniedView.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/PermissionDeniedView.kt new file mode 100644 index 0000000000..7b9738b3dc --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/view/PermissionDeniedView.kt @@ -0,0 +1,35 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.LinearLayout +import androidx.databinding.DataBindingUtil +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.databinding.VkycMandatoryPermissionBannerLayoutBinding + +class PermissionDeniedView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { + private val binding: VkycMandatoryPermissionBannerLayoutBinding + + init { + val inflater = LayoutInflater.from(context) + binding = + DataBindingUtil.inflate( + inflater, + R.layout.vkyc_mandatory_permission_banner_layout, + this, + true + ) + } + + fun setCallback(action: () -> Unit) { + binding.root.setOnClickListener { action.invoke() } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/viewmodel/VKYCViewModel.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/viewmodel/VKYCViewModel.kt new file mode 100644 index 0000000000..5c2ad318f5 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/presentation/viewmodel/VKYCViewModel.kt @@ -0,0 +1,169 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.presentation.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.navi.common.model.RedirectPageStatus +import com.navi.common.model.vkyc.VkycCancelStatus +import com.navi.common.model.vkyc.VkycSettingsResponse +import com.navi.common.model.vkyc.VkycStatus +import com.navi.common.model.vkyc.WaitingPageDetailsResponse +import com.navi.common.permission.Permission +import com.navi.common.permission.PermissionTypeGranted +import com.navi.common.permission.UpdateDevicePermissionsRequest +import com.navi.common.viewmodel.BaseVM +import com.navi.navi_vkyc.data.VkycRepository +import com.navi.navi_vkyc.models.PermissionDetailsResponse +import com.navi.navi_vkyc.util.API_ERROR_CONSTNATS +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import kotlinx.coroutines.launch + +@HiltViewModel +class VKYCViewModel @Inject constructor(val repository: VkycRepository) : BaseVM() { + private val _permissionDetailsResponse = MutableLiveData() + val permissionDetailsResponse: LiveData + get() = _permissionDetailsResponse + + private val _vkycSettingsResponse = MutableLiveData() + val vkycSettingsResponse: LiveData + get() = _vkycSettingsResponse + + private val _waitingPageDetailsResponse = MutableLiveData() + val waitingPageDetailsResponse: LiveData + get() = _waitingPageDetailsResponse + + private val _cancelVkycResponse = MutableLiveData() + val cancelVkycResponse: LiveData + get() = _cancelVkycResponse + + private val _vkycStatusResponse = MutableLiveData() + val vkycStatusResponse: LiveData + get() = _vkycStatusResponse + + private val _vkycAgentAssignedStatusResponse = MutableLiveData() + val vkycAgentAssignedStatusResponse: LiveData + get() = _vkycAgentAssignedStatusResponse + + private val _kycStatus = MutableLiveData() + val kycStatus: LiveData + get() = _kycStatus + + private val _vkycPermissionSubmitResponse = MutableLiveData() + val vkycPermissionSubmitResponse: LiveData + get() = _vkycPermissionSubmitResponse + + fun fetchPermissionDetails(callingModule: String) { + viewModelScope.launch { + val response = repository.fetchPermissionDetails(callingModule) + val permissionDetails = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + permissionDetails.let { _permissionDetailsResponse.postValue(it) } + } else { + setErrorData(response.errors, response.error) + } + } + } + + fun fetchVkycSettings(callingModule: String, latitude: Double, longitude: Double) { + viewModelScope.launch { + val response = repository.fetchVkycSettings(callingModule, latitude, longitude) + val vkycSettings = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + vkycSettings.let { _vkycSettingsResponse.postValue(it) } + } else { + setErrorData(response.errors, response.error, API_ERROR_CONSTNATS.VKYC_SETTINGS) + } + } + } + + fun fetchWaitingPageDetails(callingModule: String) { + viewModelScope.launch { + val response = repository.fetchWaitingPageDetails(callingModule) + val waitingPageDetails = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + waitingPageDetails.let { _waitingPageDetailsResponse.postValue(it) } + } else { + setErrorData(response.errors, response.error) + } + } + } + + fun cancelVkyc(callingModule: String) { + viewModelScope.launch { + val response = repository.cancelVkyc(callingModule) + val cancelResponse = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + cancelResponse.let { _cancelVkycResponse.postValue(it) } + } else { + _cancelVkycResponse.postValue(VkycCancelStatus("false")) + // setErrorData(response.errors, response.error) + } + } + } + + fun fetchKycStatus(callingModule: String) { + viewModelScope.launch { + val response = repository.fetchKycStatus(callingModule) + if (response.error == null && response.errors.isNullOrEmpty()) { + _kycStatus.value = response.data + } else { + // setErrorData(response.errors, response.error , API_ERROR_CONSTNATS.VKYC_STATUS) + } + } + } + + fun fetchVkycStatus(callingModule: String) { + viewModelScope.launch { + val response = repository.fetchVkycStatus(callingModule) + val vkycStatus = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + vkycStatus.let { _vkycStatusResponse.postValue(it) } + } else { + setErrorData(response.errors, response.error) + } + } + } + + fun fetchVkycAgentAssignedStatus(callingModule: String) { + viewModelScope.launch { + val response = repository.fetchVkycAgentAssignedStatus(callingModule) + val vkycAgentAssignedStatus = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + vkycAgentAssignedStatus.let { _vkycAgentAssignedStatusResponse.postValue(it) } + } else { + // setErrorData(response.errors, response.error, + // API_ERROR_CONSTNATS.VKYC_AGENT_ASSIGNED) + } + } + } + + fun submitPermission(callingModule: String) { + viewModelScope.launch { + val response = + repository.submitPermission( + callingModule, + UpdateDevicePermissionsRequest( + listOf( + Permission(PermissionTypeGranted.CAMERA, true), + Permission(PermissionTypeGranted.LOCATION, true), + Permission(PermissionTypeGranted.MICROPHONE, true) + ) + ) + ) + val vkycPermissionResponse = response.data + if (response.error == null && response.errors.isNullOrEmpty()) { + vkycPermissionResponse.let { _vkycPermissionSubmitResponse.postValue(it) } + } else { + setErrorData(response.errors, response.error) + } + } + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/API_ERROR_CONSTNATS.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/API_ERROR_CONSTNATS.kt new file mode 100644 index 0000000000..6a7de3065e --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/API_ERROR_CONSTNATS.kt @@ -0,0 +1,16 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.util + +object API_ERROR_CONSTNATS { + + const val VKYC_SETTINGS = "VKYC_SETTINGS" + const val VKYC_AGENT_ASSIGNED = "VKYC_AGENT_ASSIGNED" + const val VKYC_STATUS = "VKYC_STATUS" + const val VKYC_CANCEL = "VKYC_CANCEL" +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NaviAnalytics.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NaviAnalytics.kt new file mode 100644 index 0000000000..0f73a52800 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NaviAnalytics.kt @@ -0,0 +1,106 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.util + +import androidx.annotation.Keep +import com.navi.analytics.utils.NaviTrackEvent + +@Keep +class VkycNaviAnalytics private constructor() { + + private object Holder { + val INSTANCE = VkycNaviAnalytics() + } + + inner class Permission { + fun onAllPermissionMandatoryClicked() = + NaviTrackEvent.trackEventOnClickStream( + "PL_VKYC_Permissions_AllPermissionMandatory_Clicked" + ) + + fun onLocationDeniedAndDontAskClicked() = + NaviTrackEvent.trackEventOnClickStream( + "PL_VKYC_Permissions_Location_Deny_And_Dont_Ask_Clicked" + ) + + fun onLocationPermissionDenied() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_LocationDeny_Clicked") + + fun onLocationPermissionAllow() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_LocationAllow_Clicked") + + fun onCameraPermissionDenied() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_CameraDeny_Clicked") + + fun onCameraPermissionAllow() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_CameraAllow_Clicked") + + fun onMicrophonePermissionDenied() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_MicrophoneDeny_Clicked") + + fun onMicrophonePermissionAllow() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_MicrophoneAllow_Clicked") + + fun onGPSPopupClicked(optionSelected: String) { + NaviTrackEvent.trackEventOnClickStream( + "PL_VKYC_Permissions_GPSPopup_Clicked", + mapOf(Pair("option_selected_attribute", optionSelected)) + ) + } + + fun onLandOnPermissionScreen() { + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_Landed") + } + + fun onPermissionContinueClicked() = + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Permissions_Continue_Clicked") + } + + inner class AgentWaitingScreen { + + fun onWaitingForAgentScreenShown() { + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Connect_Loader_screen_Landed") + } + + fun onBackClicked(kycReferenceId: String?) { + val map = mapOf(Pair("kyc_source_reference_id", kycReferenceId.toString())) + NaviTrackEvent.trackEventOnClickStream( + "PL_VKYC_Connect_Loader_Back_Button_Clicked", + map + ) + } + + fun onVKycCallConnected(timeInSeconds: Long, kycReferenceId: String?) { + val map = + mapOf( + Pair("TAT", timeInSeconds.toString()), + Pair("kyc_source_reference_id", kycReferenceId.toString()) + ) + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Call_Connected", map) + } + } + + inner class VerdictScreen { + + fun landedOnVerdictScreen(kycReferenceId: String?) { + val map: Map = + mapOf(Pair("kyc_source_reference_id", kycReferenceId.toString())) + NaviTrackEvent.trackEventOnClickStream("PL_VKYC_Verdict_Loader_Landed", map) + } + } + + companion object { + val naviAnalytics: VkycNaviAnalytics by lazy { Holder.INSTANCE } + + const val VKYC_SCREEN = "VKYC_SCREEN" + const val VKYC_PERMISSIONS_SCREEN = "vkyc_permissions_screen" + const val VKYC_WAITING_FOR_EXECUTIVE_SCREEN = "vkyc_waiting_for_executive_screen" + const val VKYC_MEETING_ROOM_SCREEN = "vkyc_meeting_room_screen" + const val VKYC_STATUS_CHECK_SCREEN = "vkyc_status_check_screen" + } +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NavigationUtil.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NavigationUtil.kt new file mode 100644 index 0000000000..fc0e80e6ec --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/NavigationUtil.kt @@ -0,0 +1,89 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.util + +import android.app.Activity +import android.os.Bundle +import com.navi.base.model.CtaData +import com.navi.common.deeplink.DeepLinkManager +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.util.Constants.DESCRIPTION +import com.navi.navi_vkyc.util.Constants.IS_KYC_REJECTION +import com.navi.navi_vkyc.util.Constants.PERSONAL_LOAN +import com.navi.navi_vkyc.util.Constants.TITLE +import com.navi.navi_vkyc.util.Constants.WIDGET_ID + +fun goToKYCPage(activity: Activity?) { + activity?.let { + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity = it, + ctaData = CtaData(url = "LOAN_APPLICATION_V2/KYC_V2"), + finish = true, + clearTask = true, + bundle = null + ) + } +} + +fun goToInReview(activity: Activity?) { + activity?.let { + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity = activity, + ctaData = CtaData("LOAN_APPLICATION_V2/KYC_IN_REVIEW_V2"), + bundle = + Bundle().apply { + putString( + TITLE, + activity.resources.getString(R.string.kyc_verification_pending) + ) + putString( + DESCRIPTION, + activity.resources.getString(R.string.kyc_pending_description) + ) + }, + finish = true, + clearTask = true + ) + } + activity?.let { + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity = it, + ctaData = CtaData(url = "LOAN_APPLICATION_V2/KYC_V2"), + finish = true, + clearTask = true, + bundle = null + ) + } +} + +fun goToSoftRejectPage( + activity: Activity?, +) { + val bundle = Bundle() + bundle.putString(WIDGET_ID, PERSONAL_LOAN) + bundle.putBoolean(IS_KYC_REJECTION, true) + DeepLinkManager.getDeepLinkListener() + ?.navigateTo( + activity, + ctaData = CtaData(url = "ERRORS_V2/REJECTION_V2"), + bundle = bundle, + finish = true, + clearTask = true, + ) +} + +object Constants { + const val WIDGET_ID = "WIDGET_ID" + const val IS_KYC_REJECTION = "IS_KYC_REJECTION" + const val PERSONAL_LOAN = "personal" + const val TITLE = "TITLE" + const val DESCRIPTION = "DESCRIPTION" +} diff --git a/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/PermissionUtil.kt b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/PermissionUtil.kt new file mode 100644 index 0000000000..2f7c8baf51 --- /dev/null +++ b/navi-vkyc/src/main/java/com/navi/navi_vkyc/util/PermissionUtil.kt @@ -0,0 +1,80 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.navi_vkyc.util + +import android.Manifest +import android.app.Application +import android.content.Context +import android.content.ContextWrapper +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.provider.Settings +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import com.navi.common.managers.PermissionsManager +import com.navi.common.model.permission.PermissionTile +import com.navi.navi_vkyc.R +import com.navi.navi_vkyc.common.Constants + +fun openNativePermissionPage(applicationId: String?, contextWrapper: ContextWrapper?) { + val intent = + Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse(Constants.PACKAGE.plus(applicationId)) + ) + contextWrapper?.startActivity(intent) +} + +fun getPermissionTilesForVKYC(application: Application?): List { + val list = mutableListOf() + application?.let { + val application = it.applicationContext + return listOf( + PermissionTile( + ResourcesCompat.getDrawable( + application.resources, + R.drawable.vkyc_microphone_svg, + null + ), + application.getString(R.string.vkyc_microphone), + application.getString(R.string.vkyc_microphone_permission), + listOf(Manifest.permission.RECORD_AUDIO) + ), + PermissionTile( + ResourcesCompat.getDrawable( + application.resources, + R.drawable.vkyc_camera_svg, + null + ), + application.getString(R.string.vkyc_camera), + application.getString(R.string.vkyc_camera_permission), + listOf(Manifest.permission.CAMERA) + ), + PermissionTile( + ResourcesCompat.getDrawable( + application.resources, + R.drawable.vkyc_location_svg, + null + ), + application.getString(R.string.vkyc_location), + application.getString(R.string.vkyc_location_permission), + listOf(Manifest.permission.ACCESS_FINE_LOCATION) + ) + ) + } + return list +} + +fun hasPermissions( + context: Context, + permissions: Array = PermissionsManager.requiredPermissions +): Boolean = + permissions.all { permission -> + ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED + } diff --git a/navi-vkyc/src/main/res/drawable-v24/ic_launcher_foreground.xml b/navi-vkyc/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..2b068d1146 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/doggy_waiting.xml b/navi-vkyc/src/main/res/drawable/doggy_waiting.xml new file mode 100644 index 0000000000..dd262602cd --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/doggy_waiting.xml @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/ic_agent_icon.xml b/navi-vkyc/src/main/res/drawable/ic_agent_icon.xml new file mode 100644 index 0000000000..31802c9d39 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/ic_agent_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/navi-vkyc/src/main/res/drawable/ic_bg_circle.xml b/navi-vkyc/src/main/res/drawable/ic_bg_circle.xml new file mode 100644 index 0000000000..69072409f5 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/ic_bg_circle.xml @@ -0,0 +1,9 @@ + + + diff --git a/navi-vkyc/src/main/res/drawable/ic_switch_camera.xml b/navi-vkyc/src/main/res/drawable/ic_switch_camera.xml new file mode 100644 index 0000000000..5b4c5cc67b --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/ic_switch_camera.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/rounded_rect_8dp_border_1dp.xml b/navi-vkyc/src/main/res/drawable/rounded_rect_8dp_border_1dp.xml new file mode 100644 index 0000000000..e3c370a93b --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/rounded_rect_8dp_border_1dp.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/rounded_rect_border_4_radius_24.xml b/navi-vkyc/src/main/res/drawable/rounded_rect_border_4_radius_24.xml new file mode 100644 index 0000000000..130d4cf896 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/rounded_rect_border_4_radius_24.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_alert.xml b/navi-vkyc/src/main/res/drawable/vkyc_alert.xml new file mode 100644 index 0000000000..aef23c8859 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_alert.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_bg_back_red_variant_rounded_8.xml b/navi-vkyc/src/main/res/drawable/vkyc_bg_back_red_variant_rounded_8.xml new file mode 100644 index 0000000000..f3b7634b97 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_bg_back_red_variant_rounded_8.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded.xml b/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded.xml new file mode 100644 index 0000000000..2879302769 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded_solid.xml b/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded_solid.xml new file mode 100644 index 0000000000..8ace7f0cc4 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_bg_view_bg_color_6_rounded_solid.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_bg_white_variant_8.xml b/navi-vkyc/src/main/res/drawable/vkyc_bg_white_variant_8.xml new file mode 100644 index 0000000000..56928efe4c --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_bg_white_variant_8.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_camera_svg.xml b/navi-vkyc/src/main/res/drawable/vkyc_camera_svg.xml new file mode 100644 index 0000000000..b8d45e789c --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_camera_svg.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_check.xml b/navi-vkyc/src/main/res/drawable/vkyc_check.xml new file mode 100644 index 0000000000..b2aebcd958 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_check.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_checkbox_selected_orange.xml b/navi-vkyc/src/main/res/drawable/vkyc_checkbox_selected_orange.xml new file mode 100644 index 0000000000..96f006dcb2 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_checkbox_selected_orange.xml @@ -0,0 +1,12 @@ + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_checkbox_unselected_orange.xml b/navi-vkyc/src/main/res/drawable/vkyc_checkbox_unselected_orange.xml new file mode 100644 index 0000000000..4fe2d16fd2 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_checkbox_unselected_orange.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_icon_checkbox_orange.xml b/navi-vkyc/src/main/res/drawable/vkyc_icon_checkbox_orange.xml new file mode 100644 index 0000000000..352a07b8b1 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_icon_checkbox_orange.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_info_background.xml b/navi-vkyc/src/main/res/drawable/vkyc_info_background.xml new file mode 100644 index 0000000000..97c2c3a421 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_info_background.xml @@ -0,0 +1,14 @@ + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_location_svg.xml b/navi-vkyc/src/main/res/drawable/vkyc_location_svg.xml new file mode 100644 index 0000000000..3df3fb1547 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_location_svg.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_microphone_svg.xml b/navi-vkyc/src/main/res/drawable/vkyc_microphone_svg.xml new file mode 100644 index 0000000000..a4fa2e3272 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_microphone_svg.xml @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_progressbar_horizontal_rounded_bg_white.xml b/navi-vkyc/src/main/res/drawable/vkyc_progressbar_horizontal_rounded_bg_white.xml new file mode 100644 index 0000000000..ca8615fb35 --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_progressbar_horizontal_rounded_bg_white.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/drawable/vkyc_right_arrow_bg_white.xml b/navi-vkyc/src/main/res/drawable/vkyc_right_arrow_bg_white.xml new file mode 100644 index 0000000000..9ba054a90d --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_right_arrow_bg_white.xml @@ -0,0 +1,13 @@ + + + + diff --git a/navi-vkyc/src/main/res/drawable/vkyc_security_checked_green_svg.xml b/navi-vkyc/src/main/res/drawable/vkyc_security_checked_green_svg.xml new file mode 100644 index 0000000000..75eea83a4a --- /dev/null +++ b/navi-vkyc/src/main/res/drawable/vkyc_security_checked_green_svg.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_activity.xml b/navi-vkyc/src/main/res/layout/vkyc_activity.xml new file mode 100644 index 0000000000..c1231e309a --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_activity.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/layout/vkyc_exit_confirmation.xml b/navi-vkyc/src/main/res/layout/vkyc_exit_confirmation.xml new file mode 100644 index 0000000000..5d996a47d8 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_exit_confirmation.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/layout/vkyc_footer_view.xml b/navi-vkyc/src/main/res/layout/vkyc_footer_view.xml new file mode 100644 index 0000000000..fe27acd93a --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_footer_view.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_header_with_description_view.xml b/navi-vkyc/src/main/res/layout/vkyc_header_with_description_view.xml new file mode 100644 index 0000000000..5d5330ee6a --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_header_with_description_view.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_important_note_layout.xml b/navi-vkyc/src/main/res/layout/vkyc_important_note_layout.xml new file mode 100644 index 0000000000..9c25aef719 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_important_note_layout.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_info_bottom_sheet_layout.xml b/navi-vkyc/src/main/res/layout/vkyc_info_bottom_sheet_layout.xml new file mode 100644 index 0000000000..6f9e82741d --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_info_bottom_sheet_layout.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_mandatory_permission_banner_layout.xml b/navi-vkyc/src/main/res/layout/vkyc_mandatory_permission_banner_layout.xml new file mode 100644 index 0000000000..2d257b8c91 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_mandatory_permission_banner_layout.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_meeting_room_fragment.xml b/navi-vkyc/src/main/res/layout/vkyc_meeting_room_fragment.xml new file mode 100644 index 0000000000..241712fe30 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_meeting_room_fragment.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/layout/vkyc_navi_header_view.xml b/navi-vkyc/src/main/res/layout/vkyc_navi_header_view.xml new file mode 100644 index 0000000000..58494952d0 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_navi_header_view.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_permission_fragment.xml b/navi-vkyc/src/main/res/layout/vkyc_permission_fragment.xml new file mode 100644 index 0000000000..31cb4cdfbb --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_permission_fragment.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_permission_type_layout.xml b/navi-vkyc/src/main/res/layout/vkyc_permission_type_layout.xml new file mode 100644 index 0000000000..86656910d4 --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_permission_type_layout.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-vkyc/src/main/res/layout/vkyc_status_check_fragment.xml b/navi-vkyc/src/main/res/layout/vkyc_status_check_fragment.xml new file mode 100644 index 0000000000..36106ef57a --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_status_check_fragment.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/layout/vkyc_waiting_for_executive.xml b/navi-vkyc/src/main/res/layout/vkyc_waiting_for_executive.xml new file mode 100644 index 0000000000..1718a8987e --- /dev/null +++ b/navi-vkyc/src/main/res/layout/vkyc_waiting_for_executive.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/values-night/themes.xml b/navi-vkyc/src/main/res/values-night/themes.xml new file mode 100644 index 0000000000..17a54dde9f --- /dev/null +++ b/navi-vkyc/src/main/res/values-night/themes.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/values/colors.xml b/navi-vkyc/src/main/res/values/colors.xml new file mode 100644 index 0000000000..f0aa0df8ac --- /dev/null +++ b/navi-vkyc/src/main/res/values/colors.xml @@ -0,0 +1,8 @@ + + + #FFF3F0 + #191919 + #6B6B6B + #1A000000 + #EF0000 + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/values/dimens.xml b/navi-vkyc/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..0436f3e06f --- /dev/null +++ b/navi-vkyc/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 24sp + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/values/strings.xml b/navi-vkyc/src/main/res/values/strings.xml new file mode 100644 index 0000000000..404cd18ad2 --- /dev/null +++ b/navi-vkyc/src/main/res/values/strings.xml @@ -0,0 +1,33 @@ + + navi-vkyc + Microphone + Camera + Location + To connect you with our agent + To verify your identity + To check loan serviceability in your area + Important Note: + All permissions are mandatory to complete the process + All permissions are mandatory to\ncomplete the process + Phone settings > Apps > Navi > Permissions + Know more + Your data is 100% safe. + HELP + Connecting you with an executive + We will assign you an executive at the earliest + Please do not leave this screen or close the app + Please wait... + We are verifying your given details + Note: This can take some time + Yes + No + Are you sure you want to exit? + You will have to start again if you leave right now. + Navi agent + It’s taking longer than usual. Hang on while we connect you to an executive. + Latitude: %1$f + Longitude: %1$f + Time: %1$s + KYC verification pending + Your KYC verification check is in progress. We will update you shortly + \ No newline at end of file diff --git a/navi-vkyc/src/main/res/values/themes.xml b/navi-vkyc/src/main/res/values/themes.xml new file mode 100644 index 0000000000..17a54dde9f --- /dev/null +++ b/navi-vkyc/src/main/res/values/themes.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/navi-vkyc/src/test/java/com/example/navi_vkyc/ExampleUnitTest.kt b/navi-vkyc/src/test/java/com/example/navi_vkyc/ExampleUnitTest.kt new file mode 100644 index 0000000000..ef2891bcd2 --- /dev/null +++ b/navi-vkyc/src/test/java/com/example/navi_vkyc/ExampleUnitTest.kt @@ -0,0 +1,23 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.example.navi_vkyc + +import org.junit.Assert.* +import org.junit.Test + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/navi-widgets/src/main/assets/builders_widget_background.json b/navi-widgets/src/main/assets/builders_widget_background.json new file mode 100644 index 0000000000..1a8e66d4c8 --- /dev/null +++ b/navi-widgets/src/main/assets/builders_widget_background.json @@ -0,0 +1 @@ +{"v":"5.9.0","fr":24,"ip":0,"op":65,"w":360,"h":144,"nm":"Card shimmer","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.572,"y":1},"o":{"x":0.279,"y":0},"t":19,"s":[-65.434,62.035,0],"to":[83.5,0,0],"ti":[-83.5,0,0]},{"t":54,"s":[435.566,62.035,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-12.809,-9.715,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20.383,362.57],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":99,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.5,1,0],"ix":9}},"s":{"a":0,"k":[-43.257,-53.184],"ix":5},"e":{"a":0,"k":[55.052,69.292],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.384,-4.788],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[22.62,100],"ix":3},"r":{"a":0,"k":34.546,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20.383,362.57],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":99,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.5,1,0],"ix":9}},"s":{"a":0,"k":[-43.257,-53.184],"ix":5},"e":{"a":0,"k":[55.052,69.292],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15.349,-11.275],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[111.015,100],"ix":3},"r":{"a":0,"k":34.546,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Card Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[180,72,0],"ix":2,"l":2},"a":{"a":0,"k":[180.25,72.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-208.638,66.06],[165.149,143.594],[208.638,-66.06],[-165.149,-143.594]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-180,72],[180,72],[180,-72],[-180,-72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.728,-0.079],[0,0],[-0.75,0],[0,0],[-0.728,0.079],[0,0],[0.75,0]],"o":[[-0.75,0],[0,0],[0.728,0.079],[0,0],[0.75,0],[0,0],[-0.728,-0.079],[0,0]],"v":[[-177.781,-72],[-180,-71.88],[-180,71.88],[-177.781,72],[177.781,72],[180,71.88],[180,-71.88],[177.781,-72]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.929,0.906,1,0.474,0.898,0.869,1,1,0.867,0.831,1],"ix":9}},"s":{"a":0,"k":[-121.959,104.857],"ix":5},"e":{"a":0,"k":[180.434,52.473],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.25,72.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/VerticalCheckpointWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/VerticalCheckpointWidgetLayout.kt new file mode 100644 index 0000000000..deae914683 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/VerticalCheckpointWidgetLayout.kt @@ -0,0 +1,130 @@ +package com.navi.naviwidgets + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat +import androidx.databinding.DataBindingUtil +import com.navi.design.utils.dpToPxInInt +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.CheckpointLayoutUnvisitedBinding +import com.navi.naviwidgets.databinding.CheckpointLayoutVisitedBinding +import com.navi.naviwidgets.databinding.VerticalCheckpointLayoutBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.CheckpointData +import com.navi.naviwidgets.models.response.CheckpointStatusType +import com.navi.naviwidgets.models.response.VerticalCheckpointWidget +import com.navi.naviwidgets.utils.loadUrlIntoImageView +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class VerticalCheckpointWidgetLayout +@JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr){ + private lateinit var binding: VerticalCheckpointLayoutBinding + private var checkpointView: View? = null + + fun setProperties( + verticalCheckpointData: VerticalCheckpointWidget, + widgetCallback: WidgetCallback?, + binding: VerticalCheckpointLayoutBinding + ) { + this.binding = binding + setWidgetLayoutParams(verticalCheckpointData.widgetLayoutParams(), binding.root) + this.binding.llCheckpoints.removeAllViews() + verticalCheckpointData.widgetData()?.checkpointList?.let{ + for(index in it.indices){ + checkpointView = getCheckpointView( + it[index], if (index != it.size-2) { + it[index].showGreenBackground + } else { + false + }, index + ) + if(index == 0 && it[index].status == CheckpointStatusType.COMPLETED){ + checkpointView?.setPadding(0, dpToPxInInt(16), 0, 0) + } + this.binding.llCheckpoints.addView(checkpointView) + } + } + } + + private fun getVisitedCheckpointBinding(): CheckpointLayoutVisitedBinding { + return DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.checkpoint_layout_visited, + binding.llCheckpoints, + false + ) + } + + private fun getUnvisitedCheckpointBinding(): CheckpointLayoutUnvisitedBinding { + return DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.checkpoint_layout_unvisited, + binding.llCheckpoints, + false + ) + } + + private fun getCheckpointView(checkpointData: CheckpointData, showFullBackgroundColor: Boolean, index: Int): View { + if(checkpointData.status == CheckpointStatusType.COMPLETED || checkpointData.status == CheckpointStatusType.ONGOING){ + return getVisitedCheckpointView(checkpointData, checkpointData.status, showFullBackgroundColor, index) + } + return getUnvisitedCheckpointView(checkpointData) + } + + private fun getVisitedCheckpointView( + checkpointData: CheckpointData, + statusType: CheckpointStatusType, + showFullBackgroundColor: Boolean, + index: Int + ): View { + val visitedCheckpointBinding = getVisitedCheckpointBinding() + checkpointData.stampInfo?.let { + loadUrlIntoImageView(context, it.url, visitedCheckpointBinding.stamp) + } + checkpointData.heading?.let { + visitedCheckpointBinding.title.setTextFieldData(it) + } + checkpointData.description?.let { + visitedCheckpointBinding.subTitle.setTextFieldData(it) + } + if(statusType == CheckpointStatusType.COMPLETED){ + visitedCheckpointBinding.verticalLine.setBackgroundColor(ContextCompat.getColor(context, R.color.description_color_five)) + } + else{ + if(index == 0){ + visitedCheckpointBinding.checkpointCv.setPadding(0, dpToPxInInt(16), 0, 0) + } + visitedCheckpointBinding.verticalLine.background = ContextCompat.getDrawable(context, R.drawable.dashed_line_2) + } + return setCheckpointBackground(visitedCheckpointBinding, checkpointData, showFullBackgroundColor) + } + + private fun setCheckpointBackground(visitedCheckpointBinding: CheckpointLayoutVisitedBinding, checkpointData: CheckpointData, showFullBackgroundColor: Boolean): View { + if(checkpointData.showGreenBackground && showFullBackgroundColor){ + visitedCheckpointBinding.root.setBackgroundColor(ContextCompat.getColor(context, R.color.light_yellowish_green)) + } + if(checkpointData.showGreenBackground && !showFullBackgroundColor){ + visitedCheckpointBinding.checkpointBackground.visibility = VISIBLE + } + return visitedCheckpointBinding.root + } + + private fun getUnvisitedCheckpointView(checkpointData: CheckpointData): View { + val unvisitedCheckpointBinding = getUnvisitedCheckpointBinding() + checkpointData.heading?.let { + unvisitedCheckpointBinding.title.setTextFieldData(it) + } + checkpointData.description?.let { + unvisitedCheckpointBinding.subTitle.setTextFieldData(it) + } + return unvisitedCheckpointBinding.root + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/BuilderIconsListAdapter.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/BuilderIconsListAdapter.kt new file mode 100644 index 0000000000..fcbf2ff379 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/BuilderIconsListAdapter.kt @@ -0,0 +1,52 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.adapters + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.navi.naviwidgets.databinding.LayoutBuilderInfoItemBinding +import com.navi.naviwidgets.utils.loadUrlIntoImageView + +class BuilderIconsListAdapter : + RecyclerView.Adapter() { + + private var iconsUrlList = mutableListOf() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BuilderIconsListVH { + return BuilderIconsListVH( + LayoutBuilderInfoItemBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: BuilderIconsListVH, position: Int) { + holder.bind(iconsUrlList[position]) + } + + override fun getItemCount(): Int = iconsUrlList.size + + fun updateIconsUrlList(iconsUrlList: List) { + this.iconsUrlList = iconsUrlList.toMutableList() + notifyDataSetChanged() + } + + inner class BuilderIconsListVH(private val binding: LayoutBuilderInfoItemBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(iconUrl: String) { + loadUrlIntoImageView( + context = binding.ivBuilderIcon.context, + url = iconUrl, + view = binding.ivBuilderIcon + ) + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ExpandableFaqAdapter.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ExpandableFaqAdapter.kt new file mode 100644 index 0000000000..f914a38cea --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ExpandableFaqAdapter.kt @@ -0,0 +1,113 @@ +package com.navi.naviwidgets.adapters + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.widget.AppCompatImageView +import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView +import com.navi.base.utils.isNotNull +import com.navi.base.utils.isValidIndex +import com.navi.naviwidgets.R +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.FaqListSingleItemBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.FaqsData +import com.navi.naviwidgets.models.response.TextFieldData + +class ExpandableFaqAdapter(private val widgetCallback: WidgetCallback?) : + RecyclerView.Adapter() { + private val faqsListData = mutableListOf() + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExpandableFaqsListVH { + val binding = FaqListSingleItemBinding + .inflate(LayoutInflater.from(parent.context), parent, false) + return ExpandableFaqsListVH(binding) + } + + override fun getItemCount(): Int { + return faqsListData.size + } + + override fun onBindViewHolder(holder: ExpandableFaqsListVH, position: Int) { + holder.bind(position, faqsListData.toList()) + } + + fun setData(listData: List) { + if (listData.isEmpty()) return + if (faqsListData.isEmpty()) { + faqsListData.addAll(listData) + notifyDataSetChanged() + return + } + } + + inner class ExpandableFaqsListVH(val binding: FaqListSingleItemBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(position: Int, list: List) { + val faqData: FaqsData = list[position] + faqData.apply { + setFaqTextField(this.title, binding.question, widgetCallback) + setFaqArrowIcon(this.isExpanded, binding.arrowDown) + if (faqData.isExpanded) { + setFaqTextField(this.description, binding.description, widgetCallback) + setFaqTextField(this.footerText, binding.footer, widgetCallback) + } else { + binding.description.isVisible = false + binding.footer.isVisible = false + } + binding.headerCl.setOnClickListener { + faqData.cta?.let { + widgetCallback?.onClick(it) + } + setExpandFaqClicklistener(faqData, list) + } + handleDividerVisibility(position, list.size, binding.divider) + } + } + + private fun handleDividerVisibility(position: Int, size: Int, divider: View) { + if (position < size.dec()) divider.visibility = View.VISIBLE + else divider.visibility = View.INVISIBLE + } + } + + private fun setExpandFaqClicklistener( + faqData: FaqsData, + list: List + ) { + val index = list.indexOf(faqData) + if (isValidIndex(index, list.size)) { + if (faqData.isExpanded) { + list[index].isExpanded = false + notifyItemChanged(index) + } else { + list.forEach { + it.isExpanded = false + } + list[index].isExpanded = true + notifyDataSetChanged() + } + } + } + + private fun setFaqArrowIcon(expanded: Boolean, arrowDown: AppCompatImageView) { + if (expanded) arrowDown.setBackgroundResource(R.drawable.ic_arrow_up_small_orange) + else arrowDown.setBackgroundResource(R.drawable.ic_arrow_down_small_orange) + } + + private fun setFaqTextField( + title: TextFieldData?, + textView: TextView, + widgetCallback: WidgetCallback? + ) { + if (title.isNotNull()) { + textView.isVisible = true + textView.setTextFieldData(title) { + widgetCallback?.onClick(it) + } + } else { + textView.isVisible = false + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/FreeInsurancePaymentOptionsAdapter.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/FreeInsurancePaymentOptionsAdapter.kt new file mode 100644 index 0000000000..aa62816a0e --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/FreeInsurancePaymentOptionsAdapter.kt @@ -0,0 +1,132 @@ +package com.navi.naviwidgets.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.widget.AppCompatImageView +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView +import com.navi.base.model.CtaData +import com.navi.base.utils.isNotNull +import com.navi.base.utils.isValidIndex +import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.getNaviDrawable +import com.navi.naviwidgets.R +import com.navi.naviwidgets.databinding.PaymentOptionSingleItemBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.PaymentOptions +import com.navi.naviwidgets.models.response.TextFieldData + +class FreeInsurancePaymentOptionsAdapter(private val parentContext: Context?, private val paymentSelected: (ctaData: CtaData?) -> Unit) : + RecyclerView.Adapter() { + private val paymentOptionsList = mutableListOf() + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): FreeInsurancePaymentOptionsVH { + val binding = PaymentOptionSingleItemBinding + .inflate(LayoutInflater.from(parent.context), parent, false) + return FreeInsurancePaymentOptionsVH(binding) + } + + override fun getItemCount(): Int { + return paymentOptionsList.size + } + + override fun onBindViewHolder(holder: FreeInsurancePaymentOptionsVH, position: Int) { + holder.bind(position, paymentOptionsList, paymentSelected = { + paymentSelected(it) + }) + } + + fun setData(listData: List) { + if (listData.isEmpty()) return + if (paymentOptionsList.isEmpty()) { + paymentOptionsList.addAll(listData) + notifyDataSetChanged() + return + } + } + + inner class FreeInsurancePaymentOptionsVH(val binding: PaymentOptionSingleItemBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind( + position: Int, + list: List, + paymentSelected: (ctaData: CtaData?) -> Unit + ) { + val paymentOptions = list[position] + paymentOptions.apply { + setTextViewFields(this.title, binding.insuranceOptions) + setRadioButtonStatus(this.isSelected, binding.radioBtn) + if (this.isSelected) { + paymentSelected(paymentOptions.ctaData) + if (this.finalAmount.isNotNull()) { + binding.description.isVisible = true + setTextViewFields(this.finalAmount, binding.finalPrice) + if (this.previousAmount.isNotNull()) { + setTextViewFields( + this.previousAmount, + binding.previousPrice, + ) + } + if (this.discountText.isNotNull()) { + setTextViewFields(this.discountText, binding.discountAmount) + parentContext?.let { + binding.discountAmount.background = getNaviDrawable(cornerRadius = dpToPxInInt(10), backgroundColor = ContextCompat.getColor(it, R.color.light_green_2)) + } + } + } + } else { + binding.description.isVisible = false + } + binding.paymentOption.setOnClickListener { + if (paymentOptions.isSelected.not()) setPaymentOptionsClickData( + paymentOptions, + list + ) + } + handleDividerVisibility(position, list.size, binding.divider) + } + } + + private fun handleDividerVisibility(position: Int, size: Int, divider: View) { + if (position < size.dec()) divider.visibility = View.VISIBLE + else divider.visibility = View.INVISIBLE + } + + private fun setPaymentOptionsClickData( + paymentOptions: PaymentOptions, + list: List + ) { + val index = list.indexOf(paymentOptions) + if (isValidIndex(index, list.size)) { + list.forEach { + it.isSelected = false + } + list[index].isSelected = true + notifyDataSetChanged() + } + } + + private fun setRadioButtonStatus(isSelected: Boolean, radioBtn: AppCompatImageView) { + if (isSelected) radioBtn.setBackgroundResource(R.drawable.radio_button_checked_orange) + else radioBtn.setBackgroundResource(R.drawable.radio_button_unchecked_grey) + } + + private fun setTextViewFields( + title: TextFieldData?, + textView: TextView, + ) { + if (title.isNotNull()) { + textView.isVisible = true + textView.setTextFieldData(title) + } else { + textView.isVisible = false + } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ProductBenefitsGridItemListAdapter.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ProductBenefitsGridItemListAdapter.kt new file mode 100644 index 0000000000..6e43acd146 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/ProductBenefitsGridItemListAdapter.kt @@ -0,0 +1,63 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.adapters + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.navi.naviwidgets.R +import com.navi.naviwidgets.databinding.LayoutBenefitsGridItemBinding +import com.navi.naviwidgets.models.response.ProductBenefitsGridItem +import com.navi.naviwidgets.utils.loadUrlIntoImageView + +class ProductBenefitsGridItemListAdapter( + private val benefitsItemList: List, + private val onItemClick: (Int) -> Unit +) : RecyclerView.Adapter() { + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ProductBenefitsGridItemViewHolder { + return ProductBenefitsGridItemViewHolder( + LayoutBenefitsGridItemBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ProductBenefitsGridItemViewHolder, position: Int) { + holder.bind(benefitsItemList[position]) + } + + override fun getItemCount(): Int = benefitsItemList.size + + inner class ProductBenefitsGridItemViewHolder(val binding: LayoutBenefitsGridItemBinding) : + RecyclerView.ViewHolder(binding.root) { + init { + itemView.setOnClickListener { + onItemClick(absoluteAdapterPosition) + } + } + + fun bind(item: ProductBenefitsGridItem) { + binding.data = item + item.topIcon?.url?.let { url -> + loadUrlIntoImageView( + context = binding.ivItemIcon.context, + url = url, + view = binding.ivItemIcon, + imagePlaceholder = ContextCompat.getDrawable(binding.ivItemIcon.context, R.drawable.ic_property_image_placeholder) + ) + } + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/SliderWithDotsIndicatorItemAdapter.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/SliderWithDotsIndicatorItemAdapter.kt new file mode 100644 index 0000000000..df120c4610 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/adapters/SliderWithDotsIndicatorItemAdapter.kt @@ -0,0 +1,135 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.adapters + +import android.content.res.Resources +import android.graphics.Canvas +import android.graphics.Paint +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.animation.AccelerateDecelerateInterpolator +import android.view.animation.Interpolator +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.navi.naviwidgets.databinding.LayoutSliderWidgetItemBinding +import com.navi.naviwidgets.models.response.SliderWidgetItem +import com.navi.naviwidgets.utils.setBackgroundTintList +import com.navi.naviwidgets.utils.setMargin + + +class SliderWithDotsIndicatorItemAdapter(private val itemsList: List) : + RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SliderWidgetVH { + return SliderWidgetVH( + LayoutSliderWidgetItemBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: SliderWidgetVH, position: Int) { + holder.bind(itemsList[position]) + } + + override fun getItemCount(): Int = itemsList.size + + inner class SliderWidgetVH(private val binding: LayoutSliderWidgetItemBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(item: SliderWidgetItem) { + itemView setBackgroundTintList item.widgetLayoutParams?.backgroundColor + itemView.setMargin(item.widgetLayoutParams) + binding.data = item + } + } +} + +class CirclePagerIndicatorDecoration(private val colorActive: Int, private val colorInactive: Int) : + RecyclerView.ItemDecoration() { + private val mIndicatorHeight = (DP * 15).toInt() + private val mIndicatorStrokeWidth = DP * 3 + private val mIndicatorItemLength = DP * 3 + private val mIndicatorItemPadding = DP * 10 + private val mInterpolator: Interpolator = AccelerateDecelerateInterpolator() + private val mPaint: Paint = Paint() + + override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { + super.onDrawOver(c, parent, state) + val itemCount = parent.adapter?.itemCount ?: 0 + if (itemCount <= 1) return + + val totalLength = mIndicatorItemLength * itemCount + val paddingBetweenItems = (itemCount - 1) * mIndicatorItemPadding + val indicatorTotalWidth = totalLength + paddingBetweenItems + + val indicatorStartX = (parent.width - indicatorTotalWidth) / 2f + val indicatorPosY = (parent.height - mIndicatorHeight).toFloat() + + drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount) + val layoutManager = parent.layoutManager as LinearLayoutManager? + layoutManager?.let { + val activePosition = it.findFirstVisibleItemPosition() + if (activePosition == RecyclerView.NO_POSITION) { + return + } + val activeChild = it.findViewByPosition(activePosition) + val left: Int = activeChild?.left ?: 0 + val width: Int = activeChild?.width ?: 0 + val progress: Float = mInterpolator.getInterpolation(left * -1 / width.toFloat()) + drawHighlights(c, indicatorStartX, indicatorPosY, activePosition, progress) + } + } + + private fun drawInactiveIndicators( + c: Canvas, + indicatorStartX: Float, + indicatorPosY: Float, + itemCount: Int + ) { + mPaint.color = colorInactive + val itemWidth = mIndicatorItemLength + mIndicatorItemPadding + var start = indicatorStartX + for (i in 0 until itemCount) { + c.drawCircle(start, indicatorPosY, mIndicatorItemLength / 2f, mPaint) + start += itemWidth + } + } + + private fun drawHighlights( + c: Canvas, indicatorStartX: Float, indicatorPosY: Float, + highlightPosition: Int, progress: Float + ) { + mPaint.color = colorActive + val itemWidth = mIndicatorItemLength + mIndicatorItemPadding + if (progress == 0f) { + val highlightStart = indicatorStartX + itemWidth * highlightPosition + c.drawCircle(highlightStart, indicatorPosY, mIndicatorItemLength / 2f, mPaint) + } else { + val highlightStart = indicatorStartX + itemWidth * highlightPosition + val partialLength = mIndicatorItemLength * progress + mIndicatorItemPadding * progress + c.drawCircle( + highlightStart + partialLength, + indicatorPosY, + mIndicatorItemLength / 2f, + mPaint + ) + } + } + + companion object { + private val DP: Float = Resources.getSystem().displayMetrics.density + } + + init { + mPaint.strokeWidth = mIndicatorStrokeWidth + mPaint.style = Paint.Style.STROKE + mPaint.isAntiAlias = true + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/base/ui/IconTitleDescriptionInfoCtaBottomSheet.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/base/ui/IconTitleDescriptionInfoCtaBottomSheet.kt new file mode 100644 index 0000000000..8cbc718905 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/base/ui/IconTitleDescriptionInfoCtaBottomSheet.kt @@ -0,0 +1,87 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.base.ui + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.navi.naviwidgets.R +import com.navi.naviwidgets.databinding.IconTitleDescriptionInfoCtaBottomSheetBinding +import com.navi.naviwidgets.models.response.NaviBenefitBottomSheetData +import com.navi.naviwidgets.utils.NaviWidgetIconUtils +import com.navi.naviwidgets.utils.loadUrlIntoImageView +import com.navi.naviwidgets.utils.setBackgroundTintList + +class IconTitleDescriptionInfoCtaBottomSheet: BottomSheetDialogFragment() { + + private var _binding: IconTitleDescriptionInfoCtaBottomSheetBinding? = null + private val binding get() = _binding!! + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NORMAL, R.style.SheetDialog) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = IconTitleDescriptionInfoCtaBottomSheetBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setContentView() + } + + private fun setContentView() { + arguments?.getParcelable(BOTTOM_SHEET_DATA)?.let { bottomSheetData -> + binding.apply { + this.bottomSheetData = bottomSheetData + infoCard.infoCardData = bottomSheetData.infoMessage + bottomSheetData.topIcon?.url?.let { url -> + loadUrlIntoImageView(context = ivIcon.context, url = url, view = ivIcon) + } + bottomSheetData.infoMessage?.leftIcon?.iconCode?.let { iconCode -> + infoCard.ivInfoCardIcon.setImageDrawable( + ContextCompat.getDrawable( + infoCard.ivInfoCardIcon.context, + NaviWidgetIconUtils.getIconResourceId(iconCode) + ) + ) + } + infoCard.llInfoCard setBackgroundTintList bottomSheetData.infoMessage?.backgroundColor + tvCta.setOnClickListener { + dismissAllowingStateLoss() + } + } + } + } + + companion object { + + private const val BOTTOM_SHEET_DATA = "BOTTOM_SHEET_DATA" + const val TAG = "ICON_TITLE_DESCRIPTION_INFO_CTA_BOTTOM_SHEET" + + fun newInstance(bottomSheetData: NaviBenefitBottomSheetData?): IconTitleDescriptionInfoCtaBottomSheet { + return IconTitleDescriptionInfoCtaBottomSheet().apply { + arguments = Bundle().apply { putParcelable(BOTTOM_SHEET_DATA, bottomSheetData) } + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/extensions/WidgetExt.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/extensions/WidgetExt.kt index c8a81f381c..8968129514 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/extensions/WidgetExt.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/extensions/WidgetExt.kt @@ -20,10 +20,6 @@ import android.text.SpannableString import android.text.SpannableStringBuilder import android.text.method.LinkMovementMethod import android.text.style.* -import android.text.style.AbsoluteSizeSpan -import android.text.style.ForegroundColorSpan -import android.text.style.RelativeSizeSpan -import android.text.style.TypefaceSpan import android.view.Gravity import android.text.Html import android.view.View @@ -300,9 +296,11 @@ fun TextView.setTextFieldData( if (data.shouldStrikeOff == true) { paintFlags = paintFlags or Paint.STRIKE_THRU_TEXT_FLAG } + var drawablePadding: Int? = null data.textDrawableData?.let { textDrawableData -> setCompoundDrawablesWithIntrinsicBounds( if (getImageFromIconCode(textDrawableData.left?.iconCode) != -1) { + drawablePadding = textDrawableData.left?.drawablePadding ContextCompat.getDrawable( context, getImageFromIconCode(textDrawableData.left?.iconCode) @@ -311,6 +309,7 @@ fun TextView.setTextFieldData( null }, if (getImageFromIconCode(textDrawableData.top?.iconCode) != -1) { + drawablePadding = textDrawableData.top?.drawablePadding ContextCompat.getDrawable( context, getImageFromIconCode(textDrawableData.top?.iconCode) @@ -319,6 +318,7 @@ fun TextView.setTextFieldData( null }, if (getImageFromIconCode(textDrawableData.right?.iconCode) != -1) { + drawablePadding = textDrawableData.right?.drawablePadding ContextCompat.getDrawable( context, getImageFromIconCode(textDrawableData.right?.iconCode) @@ -327,6 +327,7 @@ fun TextView.setTextFieldData( null }, if (getImageFromIconCode(textDrawableData.bottom?.iconCode) != -1) { + drawablePadding = textDrawableData.bottom?.drawablePadding ContextCompat.getDrawable( context, getImageFromIconCode(textDrawableData.bottom?.iconCode) @@ -335,13 +336,19 @@ fun TextView.setTextFieldData( null }, ) - compoundDrawablePadding = - textDrawableData.padding?.let { dpToPx(it).toInt() } - ?: run { resources.getDimensionPixelSize(R.dimen.dp_8) } + compoundDrawablePadding = if(drawablePadding != null && drawablePadding!! >= 0) { + dpToPxInInt(drawablePadding!!) + } else { + resources.getDimensionPixelSize(R.dimen.dp_8) + } } data.gravity?.let { setTextGravity(it) } - data.cta?.let { ctaData -> setOnClickListener { ctaCallback?.invoke(ctaData) } } + data.cta?.let { + if (ctaCallback != null) { + setOnClickListener { ctaCallback?.invoke(data.cta) } + } + } } } @@ -407,7 +414,7 @@ fun TextView.setSubstringStyles( textData ) - if (isValidIndexRange(textData, startEndIndex)) { + if (isValidIndexRange("$textData ", startEndIndex)) { when (styleString.font) { FontWeightEnum.BOLD.name -> { val boldSpan = @@ -504,7 +511,7 @@ fun TextView.setSubstringStyles( ) } - if (styleString.cta.isNotNull()) { + if (styleString.cta.isNotNull() && ctaCallback.isNotNull()) { movementMethod = LinkMovementMethod.getInstance() spannableString.setSpan( object : ClickableSpan() { @@ -561,7 +568,7 @@ fun isValidIndexRange(textData: String, startEndIndex: Pair): Boolean return startEndIndex.first >= 0 && startEndIndex.first < textData.length && startEndIndex.second >= 0 && - startEndIndex.second <= textData.length && + startEndIndex.second < textData.length && startEndIndex.first <= startEndIndex.second } @@ -787,6 +794,9 @@ fun LottieAnimationView.showWhenDataIsAvailable(lottieName: String?) { LottieEnums.GI_CARD_LOTTIE.name -> { setAnimation(R.raw.gi_card_lottie) } + LottieEnums.CARD_SHIMMER.name -> { + setAnimation(R.raw.policy_card_shimmer_anim) + } } repeatCount = LottieDrawable.INFINITE playAnimation() @@ -834,6 +844,7 @@ fun View.setVisibilityState(visibility: Int) { fun TextSwitcher.showWhenDataIsAvailable( textWithStyleList: List?, timer: Timer?, + period: Long = 2000, onTextChange: (SpannableStringBuilder) -> Unit ) { when { @@ -852,7 +863,7 @@ fun TextSwitcher.showWhenDataIsAvailable( messageIndex++ } } - timer?.schedule(timerTask, 0, 2000) + timer?.schedule(timerTask, 0, period) } else -> { setVisibilityState(GONE) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/AppliedUserCountWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/AppliedUserCountWidgetInfo.kt new file mode 100644 index 0000000000..4df36f295b --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/AppliedUserCountWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.AppliedUserCountWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface AppliedUserCountWidgetInfo { + fun widgetId(): String? + fun widgetData(): AppliedUserCountWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/CentredTitleSubtitleDescWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/CentredTitleSubtitleDescWidgetInfo.kt new file mode 100644 index 0000000000..3df431e66d --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/CentredTitleSubtitleDescWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.CentredTitleSubtitleDescWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface CentredTitleSubtitleDescWidgetInfo { + fun widgetId(): String? + fun widgetData(): CentredTitleSubtitleDescWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/DashboardInsuranceDetailsWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/DashboardInsuranceDetailsWidgetInfo.kt index cd37934cff..3dfe74549f 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/DashboardInsuranceDetailsWidgetInfo.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/DashboardInsuranceDetailsWidgetInfo.kt @@ -11,7 +11,10 @@ package com.navi.naviwidgets.interfaces import com.navi.base.model.ActionData import com.navi.naviwidgets.models.response.GenericBottomSheetData +import com.navi.naviwidgets.models.response.ImageFieldData +import com.navi.naviwidgets.models.response.dashboard.DashboardInsuranceDetailsWidgetFooterBanner import com.navi.naviwidgets.models.response.dashboard.DashboardInsuranceDetailsWidgetOfferBanner +import com.navi.naviwidgets.models.response.dashboard.Tag interface DashboardInsuranceDetailsWidgetInfo { fun headerText(): String? @@ -19,14 +22,21 @@ interface DashboardInsuranceDetailsWidgetInfo { fun headerBgColor(): String? fun leftTopText(): String? fun leftTopSubText(): String? + fun leftTopSubTextSize(): Float? fun leftBottomText(): String? fun leftBottomSubText(): String? + fun leftBottomSubTextSize(): Float? + fun leftBottomRightIcon(): ImageFieldData? fun rightTopText(): String? fun rightTopSubText(): String? + fun rightTopSubTextSize(): Float? fun rightTopMoreDetailsIconUrl(): String? fun rightTopMoreDetails(): GenericBottomSheetData? fun rightBottomText(): String? fun rightBottomSubText(): String? + fun rightBottomSubTextSize(): Float? + fun getTag(): Tag? fun actionData(): ActionData? fun offerData(): DashboardInsuranceDetailsWidgetOfferBanner? + fun footerData(): DashboardInsuranceDetailsWidgetFooterBanner? } \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ExpandableFaqWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ExpandableFaqWidgetInfo.kt new file mode 100644 index 0000000000..17ae24cacc --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ExpandableFaqWidgetInfo.kt @@ -0,0 +1,15 @@ +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.ExpandableFaqWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface ExpandableFaqWidgetInfo { + fun widgetId(): String? + fun widgetData(): ExpandableFaqWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FooterWithTitleAndButtonInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FooterWithTitleAndButtonInfo.kt new file mode 100644 index 0000000000..c9ea3678d8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FooterWithTitleAndButtonInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.FooterWithTitleAndButtonBody +import com.navi.naviwidgets.models.response.WidgetError + +interface FooterWithTitleAndButtonInfo { + fun widgetId(): String? + fun widgetData(): FooterWithTitleAndButtonBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsurancePaymentWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsurancePaymentWidgetInfo.kt new file mode 100644 index 0000000000..4272000f5f --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsurancePaymentWidgetInfo.kt @@ -0,0 +1,15 @@ +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.FreeInsurancePaymentWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface FreeInsurancePaymentWidgetInfo { + fun widgetId(): String? + fun widgetData(): FreeInsurancePaymentWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsuranceSuccessWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsuranceSuccessWidgetInfo.kt new file mode 100644 index 0000000000..1ff44dc272 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/FreeInsuranceSuccessWidgetInfo.kt @@ -0,0 +1,29 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.base.model.CtaData +import com.navi.base.model.GenericAnalytics +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.Gradient +import com.navi.naviwidgets.models.response.TextFieldData + +interface FreeInsuranceSuccessWidgetInfo { + + fun headerText(): TextFieldData? + fun descriptionText(): TextFieldData? + fun footerText(): TextFieldData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun iconCode(): String? + fun gradient(): Gradient? + fun diseaseAnimationId(): String? + fun successAnimationId(): String? + fun cta(): CtaData? + fun metaData(): GenericAnalytics? + fun backgroundGradient(): Gradient? +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/HorizontalImageScrollWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/HorizontalImageScrollWidgetInfo.kt new file mode 100644 index 0000000000..0f17cf7782 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/HorizontalImageScrollWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.HorizontalImageScrollWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface HorizontalImageScrollWidgetInfo { + fun widgetId(): String? + fun widgetData(): HorizontalImageScrollWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsCardWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsCardWidgetInfo.kt new file mode 100644 index 0000000000..1a694bebd2 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsCardWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.PolicyDetailsCardWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface PolicyDetailsCardWidgetInfo { + fun widgetId(): String? + fun widgetData(): PolicyDetailsCardWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsWidgetInfo.kt new file mode 100644 index 0000000000..1de1df62bc --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/PolicyDetailsWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.PolicyDetailsWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface PolicyDetailsWidgetInfo { + fun widgetId(): String? + fun widgetData(): PolicyDetailsWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductBenefitsGridWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductBenefitsGridWidgetInfo.kt new file mode 100644 index 0000000000..ebd96d9b20 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductBenefitsGridWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.ProductBenefitsGridWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface ProductBenefitsGridWidgetInfo { + fun widgetId(): String? + fun widgetData(): ProductBenefitsGridWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductClickCardWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductClickCardWidgetInfo.kt new file mode 100644 index 0000000000..a7ade0c815 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductClickCardWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.ProductClickCardWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface ProductClickCardWidgetInfo { + fun widgetId(): String? + fun widgetData(): ProductClickCardWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductIntroWithButtonWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductIntroWithButtonWidgetInfo.kt new file mode 100644 index 0000000000..00f4cc8101 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/ProductIntroWithButtonWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.ProductIntroWithButtonWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface ProductIntroWithButtonWidgetInfo { + fun widgetId(): String? + fun widgetData(): ProductIntroWithButtonWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/SliderWithDotsIndicatorWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/SliderWithDotsIndicatorWidgetInfo.kt new file mode 100644 index 0000000000..bdf6d712a8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/SliderWithDotsIndicatorWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.SliderWithDotIndicatorWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface SliderWithDotsIndicatorWidgetInfo { + fun widgetId(): String? + fun widgetData(): SliderWithDotIndicatorWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TitleDescIconCtaWidgetinfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TitleDescIconCtaWidgetinfo.kt new file mode 100644 index 0000000000..578b429b59 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TitleDescIconCtaWidgetinfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.TitleDescIconCtaWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface TitleDescIconCtaWidgetinfo { + fun widgetId(): String? + fun widgetData(): TitleDescIconCtaWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TrustedBuilderWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TrustedBuilderWidgetInfo.kt new file mode 100644 index 0000000000..5aa9005cb8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TrustedBuilderWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.TrustedBuilderWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface TrustedBuilderWidgetInfo { + fun widgetId(): String? + fun widgetData(): TrustedBuilderWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TwoInfoCardsWithTitleWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TwoInfoCardsWithTitleWidgetInfo.kt new file mode 100644 index 0000000000..fa2926d88f --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/TwoInfoCardsWithTitleWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.TwoInfoCardsWithTitleWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface TwoInfoCardsWithTitleWidgetInfo { + fun widgetId(): String? + fun widgetData(): TwoInfoCardsWithTitleWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/UnderstandProcessVideoWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/UnderstandProcessVideoWidgetInfo.kt new file mode 100644 index 0000000000..165e0fbd6f --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/UnderstandProcessVideoWidgetInfo.kt @@ -0,0 +1,22 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.UnderstandProcessVideoWidgetData +import com.navi.naviwidgets.models.response.WidgetError + +interface UnderstandProcessVideoWidgetInfo { + fun widgetId(): String? + fun widgetData(): UnderstandProcessVideoWidgetData? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/VerticalCheckpointWidgetInfo.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/VerticalCheckpointWidgetInfo.kt new file mode 100644 index 0000000000..8b151e5991 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/interfaces/VerticalCheckpointWidgetInfo.kt @@ -0,0 +1,15 @@ +package com.navi.naviwidgets.interfaces + +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.models.response.VerticalCheckpointWidgetBody +import com.navi.naviwidgets.models.response.WidgetError + +interface VerticalCheckpointWidgetInfo { + fun widgetId(): String? + fun widgetData(): VerticalCheckpointWidgetBody? + fun widgetLayoutParams(): WidgetLayoutParams? + fun isDependentWidget(): Boolean + fun setDependencyWidgetState(isShowing: Boolean) + fun widgetError(): WidgetError? + fun widgetError(widgetError: WidgetError?) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/FreeInsurancePaymentWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/FreeInsurancePaymentWidget.kt new file mode 100644 index 0000000000..2d2906e36a --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/FreeInsurancePaymentWidget.kt @@ -0,0 +1,68 @@ +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.FreeInsurancePaymentWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class FreeInsurancePaymentWidget( + @SerializedName("widgetData") + val freeInsurancePaymentWidgetBody: FreeInsurancePaymentWidgetBody? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), FreeInsurancePaymentWidgetInfo { + + companion object { + const val WIDGET_NAME = "FI_PAYMENT_OPTIONS_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): FreeInsurancePaymentWidgetBody? = freeInsurancePaymentWidgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class FreeInsurancePaymentWidgetBody( + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("description") + val description: TextFieldData? = null, + @SerializedName("paymentOptions") + val paymentOptions: List? = null, +) + +data class PaymentOptions( + @SerializedName("isSelected") + var isSelected: Boolean = false, + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("finalAmount") + val finalAmount: TextFieldData? = null, + @SerializedName("previousAmount") + val previousAmount: TextFieldData? = null, + @SerializedName("discountText") + val discountText: TextFieldData? = null, + @SerializedName("cta") + val ctaData: CtaData? = null, +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/LargeBannerWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/LargeBannerWidget.kt new file mode 100644 index 0000000000..5dcc0caa33 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/LargeBannerWidget.kt @@ -0,0 +1,66 @@ +package com.navi.naviwidgets.models + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData +import com.navi.base.model.GenericAnalytics +import com.navi.naviwidgets.models.response.Gradient +import com.navi.naviwidgets.models.response.WidgetError +import com.navi.naviwidgets.widgets.textdisplay.Padding +import java.io.Serializable + +data class LargeBannerWidget( + @SerializedName("widgetId") + override val widgetId: String?, + @SerializedName("widgetName") + override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") + val widgetData: LargeBannerWidgetData? = null, + + override val isDependentWidget: Boolean?, + override val dependencyWidgetId: String?, + override var isDependencyWidgetShowing: Boolean?, + override var widgetError: WidgetError? +) : NaviWidget(), Serializable { + companion object { + const val WIDGET_NAME = "LARGE_BANNER_WIDGET" + } +} + +data class LargeBannerWidgetData( + @SerializedName("title", alternate = ["titleAttribute"]) + val title: NaviTextComponent? = null, + @SerializedName("subtitle", alternate = ["subtitleAttribute"]) + val subtitle: NaviTextComponent? = null, + @SerializedName("actionData") + val actionData: ActionData? = null, + @SerializedName("buttonData") + val buttonData: ButtonData? = null, + @SerializedName("gradient") + val gradient: Gradient? = null, + @SerializedName("imageUrl") + val imageUrl: String? = null, + @SerializedName("imagePadding") + val imagePadding: Padding? = null, + @SerializedName("tag") + val tagData: TagData? = null, + @SerializedName("lottieFileName") + val lottieFileName: String? = null, + @SerializedName("metaData") + val metadata: GenericAnalytics? = null +) + +data class ButtonData( + @SerializedName("title", alternate = ["titleAttribute"]) + val title: NaviTextComponent? = null, + @SerializedName("rightIconCode") + val rightIconCode: String? = null, + @SerializedName("bgColor") + val bgColor: String? = null +) + +data class TagData( + @SerializedName("title") + val title: NaviTextComponent? = null, + @SerializedName("gradient") + val gradient: Gradient? = null +) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/NaviWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/NaviWidget.kt index 76a1e3b2b0..a8d91a6aed 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/NaviWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/NaviWidget.kt @@ -10,6 +10,7 @@ package com.navi.naviwidgets.models import android.os.Parcelable import com.google.firebase.Timestamp import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.response.Gradient import com.navi.naviwidgets.models.response.WidgetError import kotlinx.android.parcel.Parcelize import java.io.Serializable @@ -58,5 +59,9 @@ data class WidgetLayoutParams( @SerializedName("rootPadding") val rootPadding: String? = null, @SerializedName("backgroundColor") - val backgroundColor: String? = null + val backgroundColor: String? = null, + @SerializedName("gradient") + val gradient: Gradient? = null, + @SerializedName("cornerRadius") + val cornerRadius: Int? = null ) : Parcelable \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/PostDisbursalSuccessWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/PostDisbursalSuccessWidget.kt new file mode 100644 index 0000000000..b5043507ba --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/PostDisbursalSuccessWidget.kt @@ -0,0 +1,29 @@ +package com.navi.naviwidgets.models + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.response.WidgetError + +data class PostDisbursalSuccessWidget( + @SerializedName("widgetId") + override val widgetId: String?, + @SerializedName("widgetName") + override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") + val postDisbursalSuccessWidgetData: PostDisbursalSuccessWidgetData? = null, + + override val isDependentWidget: Boolean?, + override val dependencyWidgetId: String?, + override var isDependencyWidgetShowing: Boolean?, + override var widgetError: WidgetError? +) : NaviWidget() { + companion object { + const val WIDGET_NAME = "POST_DISBURSAL_SUCCESS_WIDGET" + } +} + +data class PostDisbursalSuccessWidgetData( + @SerializedName("header") + val header: TitleWidgetHeader? = null, + @SerializedName("items") + val items: List? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/TitleWithListWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/TitleWithListWidget.kt index 2df95e890f..642437bf01 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/TitleWithListWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/TitleWithListWidget.kt @@ -37,5 +37,7 @@ data class TitleWidgetHeader( @SerializedName("iconUrl") val iconUrl: String? = null, @SerializedName("gradient") - val gradient: Gradient? = null + val gradient: Gradient? = null, + @SerializedName("bgColor") + val bgColor: String? = null, ) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AdvertisementWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AdvertisementWidget.kt index bbadf565ef..c47127a260 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AdvertisementWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AdvertisementWidget.kt @@ -53,13 +53,16 @@ data class ContentData( @SerializedName("description") val description: TextWithStyle? = null, @SerializedName("offerData") val offerData: TextWithStyle? = null, @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("gradient") val gradient: Gradient? = null, @SerializedName("subsequentLoanLandingPage") val subsequentLoanLandingPage: UpcomingLoanDetail? = null ) data class ImageData( @SerializedName("imageUrl") val imageUrl: String? = null, - @SerializedName("gravity") val gravity: String? = null + @SerializedName("gravity") val gravity: String? = null, + @SerializedName("height") val height: Int? = null, + @SerializedName("width") val width: Int? = null ) @Parcelize diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AppliedUserCountWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AppliedUserCountWidget.kt new file mode 100644 index 0000000000..331e92c0a4 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/AppliedUserCountWidget.kt @@ -0,0 +1,57 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.interfaces.AppliedUserCountWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class AppliedUserCountWidget( + @SerializedName("widgetData") val appliedUserCountWidgetData: AppliedUserCountWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), AppliedUserCountWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): AppliedUserCountWidgetData? = appliedUserCountWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "APPLIED_USER_COUNT_WIDGET" + } +} + +data class AppliedUserCountWidgetData( + val appliedCount: String? = null, + val firstUserImageUrl: String? = null, + val secondUserImageUrl: String? = null, + val title: TextWithStyle? = null +) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/CentredTitleSubtitleDescWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/CentredTitleSubtitleDescWidget.kt new file mode 100644 index 0000000000..7c326a6879 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/CentredTitleSubtitleDescWidget.kt @@ -0,0 +1,57 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.interfaces.CentredTitleSubtitleDescWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +class CentredTitleSubtitleDescWidget( + @SerializedName("widgetData") val widgetBody: CentredTitleSubtitleDescWidgetBody? = null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + CentredTitleSubtitleDescWidgetInfo { + + companion object { + const val WIDGET_NAME = "CENTERED_TITLE_SUBTITLE_DESC_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): CentredTitleSubtitleDescWidgetBody? = widgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class CentredTitleSubtitleDescWidgetBody( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subtitle") val subtitle: TextFieldData? = null, + @SerializedName("description") val description: TextFieldData? = null, +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ExpandableFaqWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ExpandableFaqWidget.kt new file mode 100644 index 0000000000..cbd4641dc6 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ExpandableFaqWidget.kt @@ -0,0 +1,62 @@ +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.ExpandableFaqWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class ExpandableFaqWidget( + @SerializedName("widgetData") + val expandableFAQsWidgetBody: ExpandableFaqWidgetBody? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_ID, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), ExpandableFaqWidgetInfo { + + companion object { + const val WIDGET_NAME = "ACCORDIAN_LIST_WIDGET" + const val WIDGET_ID = "checkHealthScoreWidget" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): ExpandableFaqWidgetBody? = expandableFAQsWidgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class ExpandableFaqWidgetBody( + @SerializedName("itemList") + val faqsList: List? = null +) + +data class FaqsData( + @SerializedName("cta") + var cta: CtaData? = null, + @SerializedName("isExpanded") + var isExpanded: Boolean = false, + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("description") + val description: TextFieldData? = null, + @SerializedName("footerText") + val footerText: TextFieldData? = null, +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FooterWithTitleAndButton.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FooterWithTitleAndButton.kt new file mode 100644 index 0000000000..924052c597 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FooterWithTitleAndButton.kt @@ -0,0 +1,64 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.FooterWithTitleAndButtonInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class FooterWithTitleAndButton ( + @SerializedName("widgetData") + val footerWithTitleAndButtonBody: FooterWithTitleAndButtonBody? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), FooterWithTitleAndButtonInfo { + companion object { + const val WIDGET_NAME = "FOOTER_WITH_TITLE_AND_BUTTON" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): FooterWithTitleAndButtonBody? = footerWithTitleAndButtonBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class FooterWithTitleAndButtonBody ( + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("button") + val button: FooterButton? = null +) { + data class FooterButton ( + @SerializedName("cta") + val cta: CtaData? = null, + @SerializedName("title") + val title: TextFieldData? = null + ) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FreeInsuranceSuccessWidgetData.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FreeInsuranceSuccessWidgetData.kt new file mode 100644 index 0000000000..8c97b320e6 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/FreeInsuranceSuccessWidgetData.kt @@ -0,0 +1,66 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.base.model.GenericAnalytics +import com.navi.naviwidgets.interfaces.FreeInsuranceSuccessWidgetInfo +import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.models.WidgetLayoutParams +import java.io.Serializable + +class FreeInsuranceSuccessWidgetData( + @SerializedName("widgetId") override val widgetId: String?, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String?, + @SerializedName("widgetData") val widgetData: FreeInsuranceSuccessBody? = null, + @SerializedName("widgetLayoutParams") val widgetLayoutParams: WidgetLayoutParams? = null, + override val isDependentWidget: Boolean? = false, + override val dependencyWidgetId: String? = null, + override var isDependencyWidgetShowing: Boolean? = false, + override var widgetError: WidgetError? = null +) : NaviWidget(), Serializable, FreeInsuranceSuccessWidgetInfo { + + companion object { + const val WIDGET_NAME = "FREE_INSURANCE_SUCCESS_WIDGET" + } + + override fun headerText(): TextFieldData? = widgetData?.title + + override fun descriptionText(): TextFieldData? = widgetData?.description + + override fun footerText(): TextFieldData? = widgetData?.footerText + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun iconCode(): String? = widgetData?.iconCode + + override fun gradient(): Gradient? = widgetLayoutParams?.gradient + + override fun diseaseAnimationId(): String? = widgetData?.diseaseAnimationId + + override fun successAnimationId(): String? = widgetData?.successAnimationId + + override fun cta(): CtaData? = widgetData?.cta + + override fun metaData(): GenericAnalytics? = widgetData?.metaData + + override fun backgroundGradient(): Gradient? = widgetData?.backgroundGradient +} + +class FreeInsuranceSuccessBody( + @SerializedName("backgroundGradient") val backgroundGradient: Gradient? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("description") val description: TextFieldData? = null, + @SerializedName("footerText") val footerText: TextFieldData? = null, + @SerializedName("iconCode") val iconCode: String? = null, + @SerializedName("diseaseAnimationId") val diseaseAnimationId: String? = null, + @SerializedName("successAnimationId") val successAnimationId: String? = null, + @SerializedName("cta") val cta: CtaData? = null, + @SerializedName("metaData") val metaData: GenericAnalytics? = null, +) : Serializable diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/GenericBottomSheetData.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/GenericBottomSheetData.kt index b8bad19ffc..51d26da63e 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/GenericBottomSheetData.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/GenericBottomSheetData.kt @@ -10,9 +10,10 @@ package com.navi.naviwidgets.models.response import android.os.Parcelable import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData +import com.navi.base.model.CtaData import com.navi.design.textview.model.TextWithStyle -import java.io.Serializable import kotlinx.android.parcel.Parcelize +import java.io.Serializable @Parcelize data class GenericBottomSheetData( @@ -26,7 +27,8 @@ data class GenericBottomSheetData( @Parcelize data class InfoMessage( @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, - @SerializedName("message") val message: TextFieldData? = null + @SerializedName("message") val message: TextFieldData? = null, + @SerializedName("backgroundColor") val backgroundColor: String? = null ) : Parcelable @Parcelize @@ -35,3 +37,12 @@ data class GenericBottomSheetLineData( @SerializedName("value") val value: TextWithStyle? = null, @SerializedName("showDivider") val showDivider: Boolean? = null ) : Parcelable + +@Parcelize +data class NaviBenefitBottomSheetData( + @SerializedName("topIcon") val topIcon: ImageFieldData? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("infoCard") val infoMessage: InfoMessage? = null, + @SerializedName("cta") val cta: CtaData? = null +) : Parcelable \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeProductWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeProductWidget.kt index 33ff482e84..6ca47159b8 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeProductWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeProductWidget.kt @@ -58,7 +58,8 @@ data class ProductDetailsData( @SerializedName("lottiePadding") val lottiePadding: Padding? = null, @SerializedName("gradient") val gradient: Gradient? = null, @SerializedName("bgColor") val bgColor: String? = null, - @SerializedName("label") val label: Label? = null + @SerializedName("label") val label: Label? = null, + @SerializedName("showOnlySubProducts") val showOnlySubProducts: Boolean? = false ) : Serializable data class Label( diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductMiniWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductMiniWidget.kt new file mode 100644 index 0000000000..57492c07d8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductMiniWidget.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData +import com.navi.base.model.GenericAnalytics +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.widgets.textdisplay.Padding + +data class HomeStuProductMiniWidget( + @SerializedName("widgetId") override val widgetId: String? = null, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") + val homeStuProductMiniWidgetData: HomeStuProductMiniWidgetData? = null, + override val isDependentWidget: Boolean?, + override val dependencyWidgetId: String?, + override var isDependencyWidgetShowing: Boolean?, + override var widgetError: WidgetError?, +) : NaviWidget() { + companion object { + const val WIDGET_NAME = "HOME_STU_PRODUCT_MINI_WIDGET" + } +} + +data class HomeStuProductMiniWidgetData( + @SerializedName("bgColor") val bgColor: String? = null, + @SerializedName("titleData") val title: TextWithStyle? = null, + @SerializedName("leftIconUrl") val leftIconUrl: String? = null, + @SerializedName("leftImagePadding") val leftPadding: Padding? = null, + @SerializedName("rightIconUrl") val rightIconUrl: String? = null, + @SerializedName("rightImagePadding") val rightPadding: Padding? = null, + @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("metaData") val metaData: GenericAnalytics? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductWidget.kt new file mode 100644 index 0000000000..4d354d9ecb --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HomeStuProductWidget.kt @@ -0,0 +1,25 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.NaviWidget + +data class HomeStuProductWidget( + @SerializedName("widgetId") override val widgetId: String? = null, + @SerializedName("widgetName") override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + @SerializedName("widgetData") val homeProductWidgetData: HomeProductWidgetData? = null, + @SerializedName("isDependentWidget") override val isDependentWidget: Boolean? = null, + @SerializedName("dependencyWidgetId") override val dependencyWidgetId: String? = null, + override var isDependencyWidgetShowing: Boolean? = null, + override var widgetError: WidgetError? = null +) : NaviWidget() { + companion object { + const val WIDGET_NAME = "HOME_STU_PRODUCT_WIDGET" + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HorizontalImageScrollWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HorizontalImageScrollWidget.kt new file mode 100644 index 0000000000..e6b0f1fa93 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/HorizontalImageScrollWidget.kt @@ -0,0 +1,55 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.interfaces.HorizontalImageScrollWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class HorizontalImageScrollWidget( + @SerializedName("widgetData") + val horizontalImageScrollWidgetBody: HorizontalImageScrollWidgetBody? = null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + HorizontalImageScrollWidgetInfo { + + companion object { + const val WIDGET_NAME = "HORIZONTAL_IMAGE_SCROLL" + } + + override fun widgetId(): String? = widgetId + override fun widgetData(): HorizontalImageScrollWidgetBody? = horizontalImageScrollWidgetBody + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + override fun widgetError(): WidgetError? = widgetError + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class HorizontalImageScrollWidgetBody( + @SerializedName("onScreenItemCount") val onScreenItemCount: Float? = null, + @SerializedName("itemList") val itemList: List? = null +) + +data class ItemData( + @SerializedName("url") val url: String? = null, + @SerializedName("cta") val cta: Any? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageCarousalWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageCarousalWidget.kt index 37723bd823..cffe659f91 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageCarousalWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageCarousalWidget.kt @@ -11,22 +11,19 @@ import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData import com.navi.base.model.GenericAnalytics import com.navi.design.textview.model.TextWithStyle -import com.navi.naviwidgets.models.NaviWidget +import com.navi.naviwidgets.models.GenericWidgetDataInfo data class ImageCarousalWidget( - @SerializedName("widgetId") - override val widgetId: String? = null, - @SerializedName("widgetName") - override var widgetNameForBaseAdapter: String? = WIDGET_NAME, @SerializedName("widgetData") val widgetData: ImageCarousalWidgetData? = null, - @SerializedName("isDependentWidget") - override val isDependentWidget: Boolean? = null, - @SerializedName("dependencyWidgetId") - override val dependencyWidgetId: String? = null, - override var isDependencyWidgetShowing: Boolean? = null, - override var widgetError: WidgetError? = null -) : NaviWidget() { +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = null, + dependencyWidgetId = null, + isDependencyWidgetShowing = null, + widgetError = null +) { companion object { const val WIDGET_NAME = "IMAGE_BANNER_WIDGET" } @@ -48,9 +45,9 @@ data class ImageCarousalWidgetData( @SerializedName("metaData") val metaData: GenericAnalytics? = null, @SerializedName("label") - val label: LabelData? = null , + val label: LabelData? = null, @SerializedName("titleV2") - val titleV2 : TextWithStyle ?= null + val titleV2: TextWithStyle? = null ) data class Banner( @@ -60,4 +57,6 @@ data class Banner( val showBorder: Boolean? = null, @SerializedName("actionData") val actionData: ActionData? = null, + @SerializedName("metaData") + val metaData: GenericAnalytics? = null ) : RadioButtonBaseItem(ImageCarousalWidget.WIDGET_NAME) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageWithBottomTextWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageWithBottomTextWidget.kt index 6e92c24d05..8aae3464f1 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageWithBottomTextWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ImageWithBottomTextWidget.kt @@ -2,6 +2,7 @@ package com.navi.naviwidgets.models.response import android.os.Parcelable import com.google.gson.annotations.SerializedName +import com.navi.base.model.ActionData import com.navi.base.model.CtaData import com.navi.naviwidgets.models.GenericWidgetDataInfo import kotlinx.android.parcel.Parcelize @@ -42,5 +43,9 @@ data class ImageFieldData( @SerializedName("backgroundColor") val backgroundColor: String? = null, @SerializedName("cta") - val cta: CtaData? = null + val cta: CtaData? = null, + @SerializedName("drawablePadding") + val drawablePadding: Int? = null, + @SerializedName("actionData") + val actionData: ActionData? = null ) : Parcelable \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviChatTypingStatusWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviChatTypingStatusWidget.kt new file mode 100644 index 0000000000..b9c865e810 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviChatTypingStatusWidget.kt @@ -0,0 +1,30 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.firebase.Timestamp +import com.google.firebase.firestore.PropertyName +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.models.NaviChatWidget +import java.io.Serializable + +data class NaviChatTypingStatusWidget( + val hint: String? = null, + @get:PropertyName("typing") @SerializedName("typing") val typing: Boolean? = false, + @get:PropertyName("updated_at") @SerializedName("updated_at") val updatedAt: Timestamp? = null, + override var widgetNameForBaseAdapter: String? = WIDGET_NAME, + override val messageId: String? = null, + override val shouldDisplayInChatHistory: Boolean? = null, + override var rt_created_at: Timestamp? = null, + override val senderId: String? = null, + override val senderType: String? = null +) : NaviChatWidget, Serializable { + companion object { + const val WIDGET_NAME = "NAVI_CHAT_TYPING_STATUS_WIDGET" + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviErrorPageWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviErrorPageWidget.kt new file mode 100644 index 0000000000..48ed006f34 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/NaviErrorPageWidget.kt @@ -0,0 +1,10 @@ +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName + +data class NaviErrorPageWidget( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("buttonText") val buttonText: TextFieldData? = null, + @SerializedName("iconName") val iconName: String? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsCardWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsCardWidget.kt new file mode 100644 index 0000000000..5fb014de7c --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsCardWidget.kt @@ -0,0 +1,64 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.interfaces.PolicyDetailsCardWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +class PolicyDetailsCardWidget( + @SerializedName("widgetData") val widgetBody: PolicyDetailsCardWidgetBody? = null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + PolicyDetailsCardWidgetInfo { + + companion object { + const val WIDGET_NAME = "POLICY_DETAILS_CARD_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): PolicyDetailsCardWidgetBody? = widgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class PolicyDetailsCardWidgetBody( + @SerializedName("cardProperties") val cardProperties: CardProperties? = null, + @SerializedName("topIconCode") val topIconCode: String? = null, + @SerializedName("stampLottieCode") val stampLottieCode: String? = null, + @SerializedName("shimmerLottieCode") val shimmerLottieCode: String? = null, + @SerializedName("totalCoverTitle") val totalCoverTitle: TextFieldData? = null, + @SerializedName("totalCoverValue") val totalCoverValue: TextFieldData? = null, + @SerializedName("policyHolderTitle") val policyHolderTitle: TextFieldData? = null, + @SerializedName("policyHolderValue") val policyHolderValue: TextFieldData? = null, + @SerializedName("validUptoTitle") val validUptoTitle: TextFieldData? = null, + @SerializedName("validUptoValue") val validUptoValue: TextFieldData? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsWidget.kt new file mode 100644 index 0000000000..5f54ac7046 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/PolicyDetailsWidget.kt @@ -0,0 +1,92 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.models.WidgetLayoutParams +import com.navi.naviwidgets.interfaces.PolicyDetailsWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo + +data class PolicyDetailsWidget ( + @SerializedName("widgetData") + val policyDetailsWidgetBody: PolicyDetailsWidgetBody? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), PolicyDetailsWidgetInfo { + companion object { + const val WIDGET_NAME = "POLICY_DETAILS_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): PolicyDetailsWidgetBody? = policyDetailsWidgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class PolicyDetailsWidgetBody ( + @SerializedName("gradient") + val gradient: Gradient? = null, + @SerializedName("title") + val title: TextFieldData? = null, + @SerializedName("titleInfo") + val titleInfo: TextFieldData? = null, + @SerializedName("button") + val button: ClaimsButton? = null, + @SerializedName("tag") + val tag: Tag?=null, + @SerializedName("subtitle") + val subtitle: TextFieldData? = null, + @SerializedName("subtitleInfo") + val subtitleInfo: TextFieldData? = null, + @SerializedName("validityText") + val validityText: TextFieldData? = null, + @SerializedName("validityDate") + val validityDate: TextFieldData? = null, + @SerializedName("iconCode") + val iconCode: String? = null, + @SerializedName("description") + val description: TextFieldData? = null +) { + data class ClaimsButton ( + @SerializedName("backgroundColor") + val backgroundColor: String? =null, + @SerializedName("cta") + val cta: CtaData? = null, + @SerializedName("title") + val title: TextFieldData? = null + ) + + data class Tag ( + @SerializedName("backgroundColor") + val backgroundColor: String? =null, + @SerializedName("title") + val title: TextFieldData? = null + ) +} + diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductBenefitsGridWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductBenefitsGridWidget.kt new file mode 100644 index 0000000000..c92db3ed90 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductBenefitsGridWidget.kt @@ -0,0 +1,64 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.ProductBenefitsGridWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class ProductBenefitsGridWidget( + @SerializedName("widgetData") val productBenefitsGridWidgetData: ProductBenefitsGridWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), ProductBenefitsGridWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): ProductBenefitsGridWidgetData? = productBenefitsGridWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "PRODUCT_BENEFITS_GRID_WIDGET" + } +} + +data class ProductBenefitsGridWidgetData( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("spanCount") val spanCount: Int? = null, + @SerializedName("items") val benefitsGridItems: List? = null, +) + +data class ProductBenefitsGridItem( + @SerializedName("topIcon") val topIcon: ImageFieldData? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("bottomSheet") val bottomSheet: NaviBenefitBottomSheetData? = null, + @SerializedName("cta") val cta: CtaData? = null, +) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductClickCardWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductClickCardWidget.kt new file mode 100644 index 0000000000..12c726fa47 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductClickCardWidget.kt @@ -0,0 +1,63 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.ProductClickCardWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +class ProductClickCardWidget( + @SerializedName("widgetData") val widgetBody: ProductClickCardWidgetBody? = null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + ProductClickCardWidgetInfo { + + companion object { + const val WIDGET_NAME = "PRODUCT_CLICK_CARD_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): ProductClickCardWidgetBody? = widgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class ProductClickCardWidgetBody( + @SerializedName("backgroundGradient") val backgroundGradient: Gradient? = null, + @SerializedName("cardProperties") val cardProperties: CardProperties? = null, + @SerializedName("overlayIconCode") val overlayIconCode: String? = null, + @SerializedName("imageUrl") val imageUrl: String? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subtitle") val subtitle: TextFieldData? = null, + @SerializedName("rightIconCode") val rightIconCode: String? = null, + @SerializedName("cta") val cta: CtaData? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductIntroWithButtonWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductIntroWithButtonWidget.kt new file mode 100644 index 0000000000..ab23a65b07 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/ProductIntroWithButtonWidget.kt @@ -0,0 +1,60 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.base.model.ImageDetail +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.interfaces.ProductIntroWithButtonWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class ProductIntroWithButtonWidget( + @SerializedName("widgetData") val productIntroWithButtonWidgetData: ProductIntroWithButtonWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), ProductIntroWithButtonWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): ProductIntroWithButtonWidgetData? = productIntroWithButtonWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "PRODUCT_INTRO_WITH_BUTTON_WIDGET" + } +} + +data class ProductIntroWithButtonWidgetData( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("titleSlideIntervalTimeInMillis") val titleSlideIntervalTime: Long? = null, + @SerializedName("subTitles") val subTitleList: List? = null, + @SerializedName("endIcon") val endIcon: ImageDetail? = null, + @SerializedName("cta") val cta: CtaData? = null, +) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SingleImageWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SingleImageWidget.kt index 47c84efa9a..308c716bce 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SingleImageWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SingleImageWidget.kt @@ -55,5 +55,6 @@ data class SingleImageWidgetBody( @SerializedName("imageUrl") val imageUrl: String? = null, @SerializedName("cta") val cta: CtaData? = null, @SerializedName("aspectRatio") val aspectRatio: Float? = null, - @SerializedName("actionOnHide") val actionOnHide: Boolean? = false + @SerializedName("actionOnHide") val actionOnHide: Boolean? = false, + @SerializedName("type") val type: String? = null ) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SliderWithDotIndicatorWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SliderWithDotIndicatorWidget.kt new file mode 100644 index 0000000000..297b37919e --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/SliderWithDotIndicatorWidget.kt @@ -0,0 +1,63 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ImageDetail +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.interfaces.SliderWithDotsIndicatorWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class SliderWithDotIndicatorWidget( + @SerializedName("widgetData") val sliderWithDotIndicatorWidgetData: SliderWithDotIndicatorWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), SliderWithDotsIndicatorWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): SliderWithDotIndicatorWidgetData? = sliderWithDotIndicatorWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "SLIDER_WIDGET_WITH_DOTS_INDICATOR" + } +} + +data class SliderWithDotIndicatorWidgetData( + @SerializedName("sliderItems") val items: List, + @SerializedName("bannerSlideIntervalTimeInMillis") val bannerSlideIntervalTime: Long? = null, + @SerializedName("bannerInitialDelayInMillis") val bannerInitialDelay: Long? = null, +) + +data class SliderWidgetItem( + val widgetLayoutParams: WidgetLayoutParams? = null, + val startIcon: ImageDetail? = null, + val title: TextWithStyle? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TextFieldData.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TextFieldData.kt index af3b59db98..a7e44cb32c 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TextFieldData.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TextFieldData.kt @@ -38,7 +38,7 @@ data class StyleString( @SerializedName("endIndex") val endIndex: Int? = null, @SerializedName("relativeSize") val relativeSize: Double? = null, @SerializedName("underline") val underline: Boolean? = null, - @SerializedName("cta") val cta: CtaData? = null, + @SerializedName("substringCta", alternate = ["cta"]) val cta: CtaData? = null ) : Parcelable @Parcelize diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TitleDescIconCtaWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TitleDescIconCtaWidget.kt new file mode 100644 index 0000000000..ba91d4405d --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TitleDescIconCtaWidget.kt @@ -0,0 +1,67 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.naviwidgets.interfaces.TitleDescIconCtaWidgetinfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class TitleDescIconCtaWidget( + @SerializedName("widgetData") val titleDescIconCtaWidgetBody: TitleDescIconCtaWidgetBody? = null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + TitleDescIconCtaWidgetinfo { + companion object { + const val WIDGET_NAME = "TITLE_DESC_ICON_CTA_WIDGET" + } + + override fun widgetId(): String? = widgetId + + override fun widgetData(): TitleDescIconCtaWidgetBody? = titleDescIconCtaWidgetBody + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class TitleDescIconCtaWidgetBody( + @SerializedName("cta") val cta: CtaData? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("leftIcon") val leftIcon: ImageFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("chevronIconCode") val chevronIconCode: String? = null, + @SerializedName("rightText") val rightText: TextFieldData? = null, + @SerializedName("pillItemData") val pillItemData: PillItemData? = null, + @SerializedName("chevronUrl") val chevronUrl: String? = null, +) + +data class PillItemData( + @SerializedName("backgroundColor") val backgroundColor: String? = null, + @SerializedName("title") val title: TextFieldData? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TrustedBuilderWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TrustedBuilderWidget.kt new file mode 100644 index 0000000000..a4f2dc9527 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TrustedBuilderWidget.kt @@ -0,0 +1,60 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.interfaces.TrustedBuilderWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class TrustedBuilderWidget( + @SerializedName("widgetData") val trustedBuilderWidgetData: TrustedBuilderWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), TrustedBuilderWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): TrustedBuilderWidgetData? = trustedBuilderWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "TRUSTED_BUILDERS_WIDGET" + } +} + +data class TrustedBuilderWidgetData( + @SerializedName("bgImageCode") val backgroundImageCode: String? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null, + @SerializedName("builderInfo") val builderInfo: BuilderInfoData? = null +) + +data class BuilderInfoData( + @SerializedName("builderIcons") val builderIcons: List? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TwoInfoCardsWithTitleWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TwoInfoCardsWithTitleWidget.kt new file mode 100644 index 0000000000..ca5e6db131 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/TwoInfoCardsWithTitleWidget.kt @@ -0,0 +1,63 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.ImageDetail +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.interfaces.TwoInfoCardsWithTitleWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class TwoInfoCardsWithTitleWidget( + @SerializedName("widgetData") val twoInfoCardsWithTitleWidgetData: TwoInfoCardsWithTitleWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), TwoInfoCardsWithTitleWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): TwoInfoCardsWithTitleWidgetData? = twoInfoCardsWithTitleWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "TWO_INFO_CARDS_WITH_TITLE_WIDGET" + } +} + +data class TwoInfoCardsWithTitleWidgetData( + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("loanDisbursedItem") val loanDisbursedItem: InfoItemData? = null, + @SerializedName("loanApplicationsItem") val loanApplicationsItem: InfoItemData? = null, +) + +data class InfoItemData( + @SerializedName("topIcon") val topIcon: ImageDetail? = null, + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("subTitle") val subTitle: TextFieldData? = null +) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/UnderstandProcessVideoWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/UnderstandProcessVideoWidget.kt new file mode 100644 index 0000000000..55b65fd024 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/UnderstandProcessVideoWidget.kt @@ -0,0 +1,60 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.base.model.CtaData +import com.navi.design.textview.model.TextWithStyle +import com.navi.naviwidgets.interfaces.UnderstandProcessVideoWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class UnderstandProcessVideoWidget( + @SerializedName("widgetData") val understandProcessWidgetData: UnderstandProcessVideoWidgetData? = null +) : GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null +), UnderstandProcessVideoWidgetInfo { + + override fun widgetId(): String? = widgetId + + override fun widgetData(): UnderstandProcessVideoWidgetData? = understandProcessWidgetData + + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + + override fun widgetError(): WidgetError? = widgetError + + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } + + companion object { + const val WIDGET_NAME = "UNDERSTAND_PROCESS_VIDEO_WIDGET" + } +} + +data class UnderstandProcessVideoWidgetData( + @SerializedName("videoThumbnail") val videoThumbnailUrl: String? = null, + @SerializedName("videoDuration") val videoDuration: TextFieldData? = null, + @SerializedName("playIcon") val playIcon: ImageFieldData? = null, + @SerializedName("title") val title: TextFieldData? = null, + @SerializedName("subTitle") val subTitle: TextWithStyle? = null, + @SerializedName("cta") val ctaData: CtaData? = null, +) \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/VerticalCheckpointWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/VerticalCheckpointWidget.kt new file mode 100644 index 0000000000..7a6958465d --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/VerticalCheckpointWidget.kt @@ -0,0 +1,56 @@ +package com.navi.naviwidgets.models.response + +import com.google.gson.annotations.SerializedName +import com.navi.naviwidgets.interfaces.VerticalCheckpointWidgetInfo +import com.navi.naviwidgets.models.GenericWidgetDataInfo +import com.navi.naviwidgets.models.WidgetLayoutParams + +data class VerticalCheckpointWidget( + @SerializedName("widgetData") + val verticalCheckpointWidgetBody: VerticalCheckpointWidgetBody ?= null +) : + GenericWidgetDataInfo( + widgetId = WIDGET_NAME, + widgetNameForBaseAdapter = WIDGET_NAME, + isDependentWidget = false, + dependencyWidgetId = null, + isDependencyWidgetShowing = false, + widgetError = null + ), + VerticalCheckpointWidgetInfo { + + companion object { + const val WIDGET_NAME = "VERTICAL_CHECKPOINT_WIDGET" + } + + override fun widgetId(): String? = widgetId + override fun widgetData(): VerticalCheckpointWidgetBody? = verticalCheckpointWidgetBody + override fun widgetLayoutParams(): WidgetLayoutParams? = widgetLayoutParams + override fun isDependentWidget(): Boolean = isDependentWidget ?: false + override fun isDependencyWidgetShowing(): Boolean = isDependencyWidgetShowing ?: false + override fun setDependencyWidgetState(isShowing: Boolean) { + isDependencyWidgetShowing = isShowing + } + override fun widgetError(): WidgetError? = widgetError + override fun widgetError(widgetError: WidgetError?) { + this.widgetError = widgetError + } +} + +data class VerticalCheckpointWidgetBody( + @SerializedName("checkpointList") val checkpointList: List? = null +) + +data class CheckpointData( + @SerializedName("heading") val heading: TextFieldData? = null, + @SerializedName("description") val description: TextFieldData? = null, + @SerializedName("stampInfo") val stampInfo: ImageFieldData? = null, + @SerializedName("status") val status: CheckpointStatusType? = null, + @SerializedName("showGreenBackground") val showGreenBackground: Boolean = false +) + +enum class CheckpointStatusType { + COMPLETED, + ONGOING, + PENDING +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/dashboard/DashboardInsuranceDetailsWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/dashboard/DashboardInsuranceDetailsWidget.kt index 58ea0e876c..0169b6c12e 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/dashboard/DashboardInsuranceDetailsWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/models/response/dashboard/DashboardInsuranceDetailsWidget.kt @@ -12,9 +12,7 @@ import com.navi.base.model.ActionData import com.navi.design.textview.model.TextWithStyle import com.navi.naviwidgets.interfaces.DashboardInsuranceDetailsWidgetInfo import com.navi.naviwidgets.models.NaviWidget -import com.navi.naviwidgets.models.response.GenericBottomSheetData -import com.navi.naviwidgets.models.response.Gradient -import com.navi.naviwidgets.models.response.WidgetError +import com.navi.naviwidgets.models.response.* import java.io.Serializable data class DashboardInsuranceDetailsWidget( @@ -41,14 +39,22 @@ data class DashboardInsuranceDetailsWidget( override fun leftTopSubText(): String? = widgetData?.content?.leftTop?.subText + override fun leftTopSubTextSize(): Float? = widgetData?.content?.leftTop?.subTextSize + override fun leftBottomText(): String? = widgetData?.content?.leftBottom?.text override fun leftBottomSubText(): String? = widgetData?.content?.leftBottom?.subText + override fun leftBottomSubTextSize(): Float? = widgetData?.content?.leftBottom?.subTextSize + + override fun leftBottomRightIcon(): ImageFieldData? = widgetData?.content?.leftBottom?.rightIcon + override fun rightTopText(): String? = widgetData?.content?.rightTop?.text override fun rightTopSubText(): String? = widgetData?.content?.rightTop?.subText + override fun rightTopSubTextSize(): Float? = widgetData?.content?.rightTop?.subTextSize + override fun rightTopMoreDetailsIconUrl(): String? = widgetData?.content?.rightTop?.moreDetails?.imageUrl @@ -59,8 +65,16 @@ data class DashboardInsuranceDetailsWidget( override fun rightBottomSubText(): String? = widgetData?.content?.rightBottom?.subText + override fun rightBottomSubTextSize(): Float? = widgetData?.content?.rightBottom?.subTextSize + + override fun getTag(): Tag? = widgetData?.content?.tag + override fun actionData(): ActionData? = widgetData?.actionData + override fun offerData(): DashboardInsuranceDetailsWidgetOfferBanner? = widgetData?.offerBanner + + override fun footerData(): DashboardInsuranceDetailsWidgetFooterBanner? = widgetData?.footerBanner + } data class DashboardInsuranceDetailsWidgetData( @@ -68,6 +82,8 @@ data class DashboardInsuranceDetailsWidgetData( @SerializedName("content") val content: DashboardInsuranceDetailsWidgetContent? = null, @SerializedName("offerBanner") val offerBanner: DashboardInsuranceDetailsWidgetOfferBanner? = null, + @SerializedName("footerBanner") + val footerBanner: DashboardInsuranceDetailsWidgetFooterBanner? = null, @SerializedName("actionData") val actionData: ActionData? = null, ) : Serializable @@ -82,8 +98,13 @@ data class DashboardInsuranceDetailsWidgetContent( @SerializedName("leftBottom") val leftBottom: DashboardInsuranceDetailsContent? = null, @SerializedName("rightTop") val rightTop: DashboardInsuranceDetailsContent? = null, @SerializedName("rightBottom") val rightBottom: DashboardInsuranceDetailsContent? = null, + @SerializedName("tag") val tag: Tag? = null, ) : Serializable +data class Tag( + @SerializedName("title") val title: TextFieldData? = null +) + data class DashboardInsuranceDetailsWidgetOfferBanner( @SerializedName("shouldAnimate") val shouldAnimate: Boolean? = false, @SerializedName("title") val title: TextWithStyle? = null, @@ -95,9 +116,19 @@ data class DashboardInsuranceDetailsWidgetOfferBanner( @SerializedName("actionData") val actionData: ActionData? = null ) : Serializable +data class DashboardInsuranceDetailsWidgetFooterBanner( + @SerializedName("title") val title: TextWithStyle? = null, + @SerializedName("subTitle") val subTitle: TextWithStyle? = null, + @SerializedName("leftIcon") val leftIcon: String? = null, + @SerializedName("gradient") val gradient: Gradient? = null, + @SerializedName("actionData") val actionData: ActionData? = null +) : Serializable + data class DashboardInsuranceDetailsContent( @SerializedName("text") val text: String? = null, @SerializedName("subText") val subText: String? = null, + @SerializedName("subTextSize") val subTextSize: Float? = null, + @SerializedName("rightIcon") val rightIcon: ImageFieldData? = null, @SerializedName("actionIcon") val moreDetails: DashboardInsuranceMoreDetailsContent? = null ) : Serializable diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Constants.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Constants.kt index af43257ad0..9c3d3ef3a8 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Constants.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Constants.kt @@ -84,4 +84,8 @@ const val UPLOADING_STATE = "loading" const val FAILURE_AND_RETRY_STATE = "failure" const val ZERO_STRING = "0" const val APP_UPDATE_ENABLE = "APP_UPDATE_ENABLE" -const val CURRENT_VERSION_IN_STORE = "CURRENT_VERSION_IN_STORE" \ No newline at end of file +const val CURRENT_VERSION_IN_STORE = "CURRENT_VERSION_IN_STORE" +const val EMAIL_ID_PARAM = "emailId" +const val EMAIL_SUBJECT_PARAM = "emailSubject" +const val EMAIL_BODY_PARAM = "emailBody" +const val CHOOSER_TITLE_PARAM = "chooserTitle" \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/LottieEnums.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/LottieEnums.kt index e349040f04..95ae8a83df 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/LottieEnums.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/LottieEnums.kt @@ -11,5 +11,7 @@ enum class LottieEnums { HL_OFFER_LOTTIE, HL_TOP_UP_LOTTIE, GI_CARD_LOTTIE, - NAVI_REWARDS_GOLD + NAVI_REWARDS_GOLD, + CARD_SHIMMER, + } \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/NaviWidgetIconUtils.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/NaviWidgetIconUtils.kt index 35906a232b..efde663522 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/NaviWidgetIconUtils.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/NaviWidgetIconUtils.kt @@ -169,6 +169,9 @@ object NaviWidgetIconUtils { private const val INSURANCE_FAMILY = "INSURANCE_FAMILY" private const val INSURANCE_DOCTOR = "INSURANCE_DOCTOR" private const val INSURANCE_HOSPITAL = "INSURANCE_HOSPITAL" + private const val INSURANCE_HOSPITAL_SMALL = "INSURANCE_HOSPITAL_SMALL" + private const val INSURANCE_UMBRELLA = "INSURANCE_UMBRELLA" + private const val BADGE_PLUS_UPGRADE = "BADGE_PLUS_UPGRADE" private const val NEW_SHARE_ICON = "NEW_SHARE_ICON" private const val ICON_ERROR_EXCLAMATION = "ICON_ERROR_EXCLAMATION" private const val OUTLINED_ERROR_ICON_BLACK = "OUTLINED_ERROR_ICON_BLACK" @@ -194,6 +197,7 @@ object NaviWidgetIconUtils { private const val REQUEST_PROCESSING = "REQUEST_PROCESSING" private const val REQUEST_PROCESSED = "REQUEST_PROCESSED" private const val AUTO_DEBIT_PROCESSING = "AUTO_DEBIT_PROCESSING" + private const val CONFETTI_RED_ICON = "CONFETTI_RED_ICON" private const val CONFETTI_FILLED_ICON = "CONFETTI_FILLED_ICON" private const val AUTO_DEBIT_SUCCESSFUL = "AUTO_DEBIT_SUCCESSFUL" private const val ICON_SINGLE_UNSELECTED = "ICON_SINGLE_UNSELECTED" @@ -228,7 +232,7 @@ object NaviWidgetIconUtils { private const val INSURANCE_HAND_SHIELD = "INSURANCE_HAND_SHIELD" private const val RED_ICON_CROSS = "RED_ICON_CROSS" private const val EMPTY_STATE = "EMPTY_STATE" - private const val CROSS = "CROSS" + const val CROSS = "CROSS" private const val ARROW_TERTIARY = "ARROW_TERTIARY" private const val EXCLAMATION_TOAST = "EXCLAMATION_TOAST" private const val YELLOW_EXCLAMATION_TOAST = "YELLOW_EXCLAMATION_TOAST" @@ -239,6 +243,9 @@ object NaviWidgetIconUtils { private const val SPLIT_COLOR_HOUR_GLASS = "SPLIT_COLOR_HOUR_GLASS" private const val SPLIT_COLOR_RUPEE = "SPLIT_COLOR_RUPEE" private const val SPLIT_COLOR_WALLET = "SPLIT_COLOR_WALLET" + private const val HAND_UPGRADE = "HAND_UPGRADE" + private const val RIGHT_ARROW_IN_ORANGE_CIRCLE = "RIGHT_ARROW_IN_ORANGE_CIRCLE" + private const val RIGHT_ARROW_IN_BLUE_CIRCLE = "RIGHT_ARROW_IN_BLUE_CIRCLE" private const val ANNOUNCEMENT_GOLD_ICON = "ANNOUNCEMENT_GOLD_ICON" private const val ANNOUNCEMENT_CASH_ICON = "ANNOUNCEMENT_CASH_ICON" private const val PL_REWARDS_ANNOUNCEMENT_ICON = "PL_REWARDS_ANNOUNCEMENT_ICON" @@ -246,6 +253,33 @@ object NaviWidgetIconUtils { private const val ACCOUNT_TYPE_ORANGE = "ACCOUNT_TYPE_ORANGE" private const val VERIFY_OTP_ORANGE = "VERIFY_OTP_ORANGE" private const val ICON_BIG_ERROR_RED = "ICON_BIG_ERROR_RED" + const val ICON_ERROR_OUTLINED_ROUND_EXCLAMATION = "ICON_ERROR_OUTLINED_ROUND_EXCLAMATION" + private const val NEW_NAVI_HEALTH_INSURANCE_LOGO = "NEW_NAVI_HEALTH_INSURANCE_LOGO" + private const val RIGHT_ARROW_WITH_TRANSLUCENT_BACKGROUND = + "RIGHT_ARROW_WITH_TRANSLUCENT_BACKGROUND" + private const val TRANSLUCENT_VIDEO_OVERLAY = "TRANSLUCENT_VIDEO_OVERLAY" + private const val LEFT_CONFETTI_POP_ICON = "LEFT_CONFETTI_POP_ICON" + private const val RIGHT_CONFETTI_POP_ICON = "RIGHT_CONFETTI_POP_ICON" + private const val RED_LOCK_ICON = "RED_LOCK_ICON" + private const val NEW_NAVI_LOGO_IN_WHITE_CARD = "NEW_NAVI_LOGO_IN_WHITE_CARD" + private const val ICON_CLOCK_TICKING = "ICON_CLOCK_TICKING" + private const val ICON_HANDS_WITH_HEART = "ICON_HANDS_WITH_HEART" + private const val ICON_EXPIRED = "ICON_EXPIRED" + private const val ICON_CROSS_BLACK = "ICON_CROSS_BLACK" + private const val GIFT_ICON_WITH_CONGRATS = "GIFT_ICON_WITH_CONGRATS" + private const val EXPIRY_ALERT_ICON = "EXPIRY_ALERT_ICON" + private const val READY_POLICY_ICON = "READY_POLICY_ICON" + private const val ALERT_POLICY_ICON = "ALERT_POLICY_ICON" + private const val ICON_HAND_WAVE = "ICON_HAND_WAVE" + const val EXPIRED_POLICY_ICON = "EXPIRED_POLICY_ICON" + private const val NEW_GLOWING_BULB = "NEW_GLOWING_BULB" + private const val ICON_HL_HOME_WITH_COINS = "ICON_HL_HOME_WITH_COINS" + private const val ICON_GIFT = "ICON_GIFT" + private const val ICON_RBI = "ICON_RBI" + private const val ICON_MAGNIFIER = "ICON_MAGNIFIER" + private const val ICON_LOAN_DISBURSED = "ICON_LOAN_DISBURSED" + private const val ICON_LOAN_APPLICATIONS = "ICON_LOAN_APPLICATIONS" + private const val ICON_PLAY_VIDEO = "ICON_PLAY_VIDEO" fun updateIcon( imageDetail: ImageDetail, @@ -382,6 +416,8 @@ object NaviWidgetIconUtils { HEALTH_RISK_POST_SCORE_BANNER -> R.drawable.ic_health_risk_score_post_svg ICON_INFO_DARK -> R.drawable.ic_info_dark RIGHT_ARROW_WITH_BACKGROUND -> R.drawable.right_arrow_with_background_svg + RIGHT_ARROW_WITH_TRANSLUCENT_BACKGROUND -> + R.drawable.right_arrow_with_translucent_background X_BACKGROUND_ICON -> R.drawable.ic_2x_svg ALERT_YELLOW_ICON -> R.drawable.ic_alert_yellow REWARD_INFO_ICON -> R.drawable.ic_reward_info_svg @@ -390,10 +426,14 @@ object NaviWidgetIconUtils { REWARD_ICON -> R.drawable.ic_reward_icon REWARDS_PROFILE_ICON -> R.drawable.ic_reward_profile_icon NAVI_REWARDS_ICON -> R.drawable.ic_rewards_navi + NEW_NAVI_LOGO_IN_WHITE_CARD -> R.drawable.ic_navi_logo_in_white_card + TRANSLUCENT_VIDEO_OVERLAY -> R.drawable.ic_translucent_video_play_button NAVI_LOGO -> R.drawable.ic_new_navi_logo NAVI_REWARDS_LOCK_ICON -> R.drawable.ic_rewards_lock NAVI_REWARDS_INFO_ICON -> R.drawable.ic_rewards_info INSURANCE_HOSPITAL -> R.drawable.insurance_hospital + INSURANCE_HOSPITAL_SMALL -> R.drawable.insurance_hospital_small + INSURANCE_UMBRELLA -> R.drawable.umbrella_hospital INSURANCE_DOCTOR -> R.drawable.insurance_doctor INSURANCE_FAMILY -> R.drawable.insurance_family INSURANCE_REPORT -> R.drawable.insurance_report @@ -510,6 +550,9 @@ object NaviWidgetIconUtils { GRAY_INFO -> R.drawable.grey_info PERSON_CROSS -> R.drawable.ic_kyc_rejected REFRESH_ICON -> R.drawable.refresh_icon + HAND_UPGRADE -> R.drawable.hand_upgrade + RIGHT_ARROW_IN_ORANGE_CIRCLE -> R.drawable.right_arrow_in_orange_circle + RIGHT_ARROW_IN_BLUE_CIRCLE -> R.drawable.right_arrow_in_blue_circle ANNOUNCEMENT_GOLD_ICON -> R.drawable.ic_announcement_gold ANNOUNCEMENT_CASH_ICON -> R.drawable.ic_announcement_cash PL_REWARDS_ANNOUNCEMENT_ICON -> R.drawable.ic_rewards_announcement_confetti @@ -517,6 +560,29 @@ object NaviWidgetIconUtils { ACCOUNT_TYPE_ORANGE -> R.drawable.ic_account_type_orange VERIFY_OTP_ORANGE -> R.drawable.ic_verify_otp_orange ICON_BIG_ERROR_RED -> R.drawable.ic_big_error + NEW_GLOWING_BULB -> R.drawable.ic_new_glowing_bulb + ICON_HL_HOME_WITH_COINS -> R.drawable.home_loan_intro + ICON_GIFT -> R.drawable.ic_gift_box + ICON_RBI-> R.drawable.ic_rbi_registered + ICON_MAGNIFIER-> R.drawable.ic_magnifier_lens + ICON_LOAN_DISBURSED -> R.drawable.img_loan_amount_disbursed + ICON_LOAN_APPLICATIONS -> R.drawable.image_loan_applications + ICON_ERROR_OUTLINED_ROUND_EXCLAMATION -> R.drawable.ic_error_outlined + BADGE_PLUS_UPGRADE -> R.drawable.badge_plus_upgrade + LEFT_CONFETTI_POP_ICON -> R.drawable.ic_confetti_left_pop + RIGHT_CONFETTI_POP_ICON -> R.drawable.ic_confetti_right_pop + RED_LOCK_ICON -> R.drawable.ic_lock_red + ICON_CLOCK_TICKING -> R.drawable.ic_clock_ticking + ICON_HANDS_WITH_HEART -> R.drawable.ic_hands_with_heart + ICON_EXPIRED -> R.drawable.ic_expired + ICON_CROSS_BLACK -> R.drawable.ic_rounded_cross + GIFT_ICON_WITH_CONGRATS -> R.drawable.gift_icon_with_congrats_svg + EXPIRY_ALERT_ICON -> R.drawable.exipry_alert_icon + READY_POLICY_ICON -> R.drawable.ready_policy_icon + ALERT_POLICY_ICON -> R.drawable.alert_policy_icon + EXPIRED_POLICY_ICON -> R.drawable.expired_policy_icon + ICON_HAND_WAVE -> R.drawable.icon_hand_wave + ICON_PLAY_VIDEO -> R.drawable.ic_play_video else -> -1 } } diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Utils.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Utils.kt index e44acd46b7..f3f61a2c6d 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Utils.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/utils/Utils.kt @@ -8,8 +8,10 @@ package com.navi.naviwidgets.utils import android.content.Context +import android.content.res.ColorStateList import android.graphics.Color import android.graphics.drawable.Drawable +import android.graphics.drawable.GradientDrawable import android.util.TypedValue import android.view.LayoutInflater import android.view.View @@ -34,8 +36,10 @@ import com.navi.base.model.GenericAnalyticsData import com.navi.base.utils.orZero import com.navi.design.utils.dpToPx import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.parseColorSafe import com.navi.naviwidgets.R import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.extensions.getOrientation import com.navi.naviwidgets.extensions.isValidHexColor import com.navi.naviwidgets.models.NaviWidget import com.navi.naviwidgets.models.WidgetLayoutParams @@ -59,9 +63,9 @@ fun validateRequiredLoanAmount( ): Boolean { return try { propertyPurchaseValue.isNullOrEmpty().not() && - loanAmountRequired.isNullOrEmpty().not() && - (propertyPurchaseValue?.replace(",", EMPTY)?.toLong().orZero() < - loanAmountRequired?.replace(",", EMPTY)?.toLong().orZero()) + loanAmountRequired.isNullOrEmpty().not() && + (propertyPurchaseValue?.replace(",", EMPTY)?.toLong().orZero() < + loanAmountRequired?.replace(",", EMPTY)?.toLong().orZero()) } catch (e: Exception) { false } @@ -70,7 +74,13 @@ fun validateRequiredLoanAmount( fun setWidgetLayoutParams(widgetLayoutParams: WidgetLayoutParams?, view: View) { view.setMargin(widgetLayoutParams) view.setPadding(widgetLayoutParams) - view.setBackgroundColor(widgetLayoutParams?.backgroundColor) + widgetLayoutParams?.let { it -> + if(it.gradient != null) { + view.background = getGradientDrawable(view.context, it.gradient, widgetLayoutParams.cornerRadius ?: 0) + } else if(isValidHexColor(it.backgroundColor)) { + view.background = getGradientDrawable(view.context, Gradient(startGradientColor = it.backgroundColor, endGradientColor = it.backgroundColor), widgetLayoutParams.cornerRadius ?: 0) + } + } } fun CardView.setCardProperties(cardProperties: CardProperties?) { @@ -98,10 +108,10 @@ fun MaterialCardView.setMaterialCardProperties(cardProperties: CardProperties?) cardProperties?.strokeWidth?.let { strokeWidth = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - it.toFloat(), - context.resources.displayMetrics - ) + TypedValue.COMPLEX_UNIT_DIP, + it.toFloat(), + context.resources.displayMetrics + ) .toInt() } @@ -111,6 +121,77 @@ fun MaterialCardView.setMaterialCardProperties(cardProperties: CardProperties?) } } +fun MaterialCardView.setMaterialCardStyling(cardProperties: CardProperties?) { + cardProperties?.let { cardProperties -> + cardProperties.gradientProperties?.let { + background = + getGradientDrawable(context, it, cornerRadius = cardProperties.borderRadius ?: 0) + } + cardProperties.backgroundColor?.let { backgroundColor -> + backgroundTintList = ColorStateList.valueOf(backgroundColor.parseColorSafe()) + } + cardProperties.backgroundUrl?.let {} + cardProperties.elevation?.let { + cardElevation = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + it.toFloat(), + context.resources.displayMetrics + ) + } + cardProperties.borderRadius?.let { + radius = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + it.toFloat(), + context.resources.displayMetrics + ) + } + cardProperties.strokeColor?.let { strokeColor -> + if (isValidHexColor(strokeColor)) { + strokeWidth = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + cardProperties.strokeWidth?.toFloat() ?: 1.0f, + context.resources.displayMetrics + ) + .toInt() + setStrokeColor(Color.parseColor(strokeColor)) + } + } + } +} + +fun getGradientDrawable( + context: Context?, + gradient: Gradient, + cornerRadius: Int = 0 +): GradientDrawable { + val gradientColorArray = + if (isValidHexColor(gradient.middleGradientColor)) { + intArrayOf( + gradient.startGradientColor.parseColorSafe(), + gradient.middleGradientColor.parseColorSafe(), + gradient.endGradientColor.parseColorSafe() + ) + } else { + intArrayOf( + gradient.startGradientColor.parseColorSafe(), + gradient.endGradientColor.parseColorSafe() + ) + } + val gradientDrawable = GradientDrawable(getOrientation(gradient.orientation), gradientColorArray) + context?.let { context -> + gradientDrawable.cornerRadius = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + cornerRadius.toFloat(), + context.resources.displayMetrics + ) + } + return gradientDrawable +} + fun View.setMargin(widgetLayoutParams: WidgetLayoutParams?) { val layoutParams = LinearLayout.LayoutParams(this.layoutParams.width, this.layoutParams.height) val zeroMargin = 0 @@ -139,10 +220,11 @@ fun View.setMargin(widgetLayoutParams: WidgetLayoutParams?) { fun getDividerView(context: Context, height: Int? = 0): View { val view = View(context) - val layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - dpToPx(height.orZero()).toInt() - ) + val layoutParams = + LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + dpToPx(height.orZero()).toInt() + ) view.layoutParams = layoutParams return view } @@ -214,9 +296,9 @@ fun View.setBasicLayoutParams( ) { this.layoutParams = ViewGroup.MarginLayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) .apply { this.marginStart = marginStartDp this.marginEnd = marginEndDp @@ -227,9 +309,9 @@ fun View.setBasicLayoutParams( fun String.isHtml(): Boolean { return this.contains("") || - this.contains("
") || - this.contains("") || - this.contains("") + this.contains("
") || + this.contains("") || + this.contains("") } fun NaviWidget?.getAnalyticsData(): GenericAnalytics? { @@ -239,6 +321,8 @@ fun NaviWidget?.getAnalyticsData(): GenericAnalytics? { is CustomerRatingWidget -> this.userDetailsWidgetData?.metaData is DetailsWidget -> this.detailsWidgetData?.metaData is HomeProductWidget -> this.homeProductWidgetData?.metaData + is HomeStuProductWidget -> this.homeProductWidgetData?.metaData + is HomeStuProductMiniWidget -> this.homeStuProductMiniWidgetData?.metaData is ImageCarousalWidget -> this.widgetData?.metaData is PaymentActionWidget -> this.paymentActionWidgetData?.metaData is SocialMediaAdvertisementWidget -> this.socialMediaAdvertisementWidgetData?.metaData @@ -259,14 +343,14 @@ fun sendWidgetViewedTimeAnalytics( GenericAnalyticsData( eventName = WIDGET_VIEWED_TIME, parameters = - hashMapOf( - WIDGET_ID to widgetId.orEmpty(), - WIDGET_TIME_ELAPSED to + hashMapOf( + WIDGET_ID to widgetId.orEmpty(), + WIDGET_TIME_ELAPSED to TimeUnit.MILLISECONDS.toSeconds( - Date().time - nonNullWidgetVisibleStartTime - ) + Date().time - nonNullWidgetVisibleStartTime + ) .toString() - ) + ) ) ) } @@ -287,8 +371,7 @@ fun loadUrlIntoImageView( .listener(listener) .into(view) else Glide.with(context).load(url).into(view) - } catch (e: Exception) { - } + } catch (e: Exception) {} } fun loadUrlIntoImageView( @@ -307,8 +390,7 @@ fun loadUrlIntoImageView( .diskCacheStrategy(DiskCacheStrategy.DATA) .into(view) else Glide.with(context).load(url).into(view) - } catch (e: Exception) { - } + } catch (e: Exception) {} } fun getFilteredNaviWidgets(naviWidgets: List?): List? { @@ -321,11 +403,11 @@ fun getBottomSheetWidgetData( naviWidgets: List? ): TrancheDisbursalBottomSheetWidgetData? { return (naviWidgets - ?.filterNotNull() - ?.filter { - it.widgetNameForBaseAdapter == TrancheDisbursalBottomSheetWidget.WIDGET_NAME - } - ?.getOrNull(0) as? TrancheDisbursalBottomSheetWidget?) + ?.filterNotNull() + ?.filter { + it.widgetNameForBaseAdapter == TrancheDisbursalBottomSheetWidget.WIDGET_NAME + } + ?.getOrNull(0) as? TrancheDisbursalBottomSheetWidget?) ?.widgetData } @@ -354,7 +436,10 @@ fun convertObjectToJsonString(type: T): String? { val jsonString = gson.toJson(type) try { return jsonString - } catch (e: JSONException) { - } + } catch (e: JSONException) {} return null } + +infix fun View.setBackgroundTintList(color:String?) { + this.backgroundTintList = ColorStateList.valueOf(Color.parseColor(color)) +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/AppliedUserCountWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/AppliedUserCountWidgetVH.kt new file mode 100644 index 0000000000..878205e23d --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/AppliedUserCountWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutAppliedUserCountWidgetBinding +import com.navi.naviwidgets.models.response.AppliedUserCountWidget +import com.navi.naviwidgets.widgets.AppliedUserCountWidgetLayout + +class AppliedUserCountWidgetVH(private val viewDataBinding: ViewDataBinding) : BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: AppliedUserCountWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is AppliedUserCountWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutAppliedUserCountWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/CentredTitleSubtitleDescWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/CentredTitleSubtitleDescWidgetVH.kt new file mode 100644 index 0000000000..c2c424a286 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/CentredTitleSubtitleDescWidgetVH.kt @@ -0,0 +1,36 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.CentredTitleSubtitleDescWidgetBinding +import com.navi.naviwidgets.models.response.CentredTitleSubtitleDescWidget +import com.navi.naviwidgets.widgets.CentredTitleSubtitleDescWidgetLayout + +class CentredTitleSubtitleDescWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: CentredTitleSubtitleDescWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is CentredTitleSubtitleDescWidgetLayout && viewDataBinding is CentredTitleSubtitleDescWidgetBinding) { + itemView.setProperties( + widgetData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/DashboardHolderFactoryImpl.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/DashboardHolderFactoryImpl.kt index 789907446e..42ae4278a3 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/DashboardHolderFactoryImpl.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/DashboardHolderFactoryImpl.kt @@ -43,9 +43,12 @@ class DashboardHolderFactoryImpl : ViewHolderTypeFacto private val ELEVATED_ICON_WIDGET = R.layout.elevated_icons_widget private val TEXT_WITH_UNDERLINE_WIDGET = R.layout.text_with_underline_view private val HOME_PRODUCT_WIDGET = R.layout.home_product_widget_layout + private val HOME_STU_PRODUCT_WIDGET = R.layout.home_stu_product_widget_layout + private val HOME_STU_PRODUCT_MINI_WIDGET = R.layout.home_stu_product_mini_widget_layout private val IMAGE_BANNER_WIDGET = R.layout.layout_carousal_view + private val PRODUCT_CLICK_CARD_WIDGET = R.layout.product_click_card_widget - + private val FREE_INSURANCE_SUCCESS_WIDGET = R.layout.free_insurance_success_widget } override fun type(item: NaviBaseAdapterModel): Int = @@ -62,6 +65,8 @@ class DashboardHolderFactoryImpl : ViewHolderTypeFacto is ImageTextListWidget -> IMAGE_TEXT_LIST_WIDGET is ImageTextItem -> IMAGE_TEXT_ITEM_WIDGET is HomeProductWidget -> HOME_PRODUCT_WIDGET + is HomeStuProductWidget -> HOME_STU_PRODUCT_WIDGET + is HomeStuProductMiniWidget -> HOME_STU_PRODUCT_MINI_WIDGET is DashboardAmcDetailsWidget -> DASHBOARD_AMC_DETAILS_WIDGET is TextActionWidget -> TEXT_ACTION_WIDGET is DashboardInsuranceDetailsWidget -> DASHBOARD_INSURANCE_DETAILS_WIDGET @@ -71,9 +76,11 @@ class DashboardHolderFactoryImpl : ViewHolderTypeFacto is TopProductWidget -> TOP_PRODUCT_WIDGET is ProductGridViewWidget -> PRODUCT_GRID_VIEW_WIDGET is AlertInfoWidget -> ALERT_INFO_WIDGET - is GenericWidgetDataInfo -> GENERIC_WIDGET + is FreeInsuranceSuccessWidgetData -> FREE_INSURANCE_SUCCESS_WIDGET is SeparatorWidget -> SEPARATOR_WIDGET is ImageCarousalWidget -> IMAGE_BANNER_WIDGET + is ProductClickCardWidget -> PRODUCT_CLICK_CARD_WIDGET + is GenericWidgetDataInfo -> GENERIC_WIDGET else -> Int.MAX_VALUE } @@ -89,6 +96,8 @@ class DashboardHolderFactoryImpl : ViewHolderTypeFacto PARENT_CONTAINER_WIDGET -> ParentContainerWidgetVH(parent) CHILD_CONTAINER_WIDGET -> ChildContainerWidgetVH(parent) HOME_PRODUCT_WIDGET -> HomeProductWidgetVH(parent) + HOME_STU_PRODUCT_WIDGET -> HomeStuProductWidgetVH(parent) + HOME_STU_PRODUCT_MINI_WIDGET -> HomeStuProductMiniWidgetVH(parent) TOAST_WIDGET -> ToastWidgetVH(parent) IMAGE_TEXT_LIST_WIDGET -> ImageTextListVH(parent) IMAGE_TEXT_ITEM_WIDGET -> ImageTextItemVH(parent) @@ -101,11 +110,17 @@ class DashboardHolderFactoryImpl : ViewHolderTypeFacto TOP_PRODUCT_WIDGET -> TopProductVH(parent) PRODUCT_GRID_VIEW_WIDGET -> ProductGridViewVH(parent) ALERT_INFO_WIDGET -> AlertInfoWidgetVH(parent) + HOME_PRODUCT_WIDGET -> HomeProductWidgetVH(parent) + SEPARATOR_WIDGET -> SeparatorVH(parent) + IMAGE_BANNER_WIDGET -> ImageCarousalVH(parent) + FREE_INSURANCE_SUCCESS_WIDGET -> FreeInsuranceSuccessWidgetVH(parent) + PRODUCT_CLICK_CARD_WIDGET -> ProductClickCardWidgetVH(parent) GENERIC_WIDGET -> UnknownWidgetVH(parent) HOME_PRODUCT_WIDGET -> HomeProductWidgetVH(parent) SEPARATOR_WIDGET -> SeparatorVH(parent) IMAGE_BANNER_WIDGET -> ImageCarousalVH(parent) else -> UnknownWidgetVH(parent) - } as BaseViewHolder + } + as BaseViewHolder } diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ExpandableFaqWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ExpandableFaqWidgetVH.kt new file mode 100644 index 0000000000..7707567910 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ExpandableFaqWidgetVH.kt @@ -0,0 +1,33 @@ +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ExpandableFaqsWidgetLayoutBinding +import com.navi.naviwidgets.models.response.ExpandableFaqWidget +import com.navi.naviwidgets.widgets.ExpandableFaqWidgetLayout + +class ExpandableFaqWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: ExpandableFaqWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is ExpandableFaqWidgetLayout && + viewDataBinding is ExpandableFaqsWidgetLayoutBinding + ) { + itemView.setProperties( + expandableFaqsListData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) = Unit + + override fun bindWidgetStateChanged(payload: Any?) = Unit +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FooterWithTitleAndButtonVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FooterWithTitleAndButtonVH.kt new file mode 100644 index 0000000000..3d98d318d1 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FooterWithTitleAndButtonVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.FooterWithTitleAndButtonBinding +import com.navi.naviwidgets.models.response.FooterWithTitleAndButton +import com.navi.naviwidgets.widgets.FooterWithTitleAndButtonLayout + +class FooterWithTitleAndButtonVH (private val viewDataBinding: ViewDataBinding): + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: FooterWithTitleAndButton, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if(itemView is FooterWithTitleAndButtonLayout && viewDataBinding is FooterWithTitleAndButtonBinding) { + itemView.setProperties( + infoData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) { + } + + override fun bindWidgetStateChanged(payload: Any?) { + } + + override fun onRecycled() { + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FreeInsuranceSuccessWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FreeInsuranceSuccessWidgetVH.kt new file mode 100644 index 0000000000..6b4908ecb4 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/FreeInsuranceSuccessWidgetVH.kt @@ -0,0 +1,36 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.viewbinding.ViewBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.FreeInsuranceSuccessWidgetBinding +import com.navi.naviwidgets.models.response.FreeInsuranceSuccessWidgetData +import com.navi.naviwidgets.widgets.FreeInsuranceSuccessWidgetLayout + +class FreeInsuranceSuccessWidgetVH(private val viewDataBinding: ViewBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: FreeInsuranceSuccessWidgetData, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is FreeInsuranceSuccessWidgetLayout) { + itemView.update( + binding = (viewDataBinding as FreeInsuranceSuccessWidgetBinding), + info = model, + widgetCallback = widgetCallback + ) + } + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductMiniWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductMiniWidgetVH.kt new file mode 100644 index 0000000000..3efc85912b --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductMiniWidgetVH.kt @@ -0,0 +1,39 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HomeStuProductMiniWidgetLayoutBinding +import com.navi.naviwidgets.models.response.HomeStuProductMiniWidget +import com.navi.naviwidgets.widgets.HomeStuProductMiniWidgetLayout + +class HomeStuProductMiniWidgetVH(private val viewBinding: ViewDataBinding) : + BaseViewHolder(view = viewBinding.root) { + + override fun bind( + model: HomeStuProductMiniWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is HomeStuProductMiniWidgetLayout) + itemView.update( + widgetData = model, + binding = viewBinding as HomeStuProductMiniWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} + + override fun onRecycled() {} +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductWidgetVH.kt new file mode 100644 index 0000000000..410a46b1ca --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HomeStuProductWidgetVH.kt @@ -0,0 +1,39 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HomeStuProductWidgetLayoutBinding +import com.navi.naviwidgets.models.response.HomeStuProductWidget +import com.navi.naviwidgets.widgets.HomeStuProductWidgetLayout + +class HomeStuProductWidgetVH(private val viewBinding: ViewDataBinding) : + BaseViewHolder(view = viewBinding.root) { + + override fun bind( + model: HomeStuProductWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is HomeStuProductWidgetLayout) + itemView.update( + widgetData = model, + binding = viewBinding as HomeStuProductWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} + + override fun onRecycled() {} +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HorizontalImageScrollVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HorizontalImageScrollVH.kt new file mode 100644 index 0000000000..75c273b41c --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/HorizontalImageScrollVH.kt @@ -0,0 +1,40 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HorizontalImageScrollBinding +import com.navi.naviwidgets.models.response.HorizontalImageScrollWidget +import com.navi.naviwidgets.widgets.HorizontalImageScrollWidgetLayout + +class HorizontalImageScrollVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: HorizontalImageScrollWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is HorizontalImageScrollWidgetLayout && + viewDataBinding is HorizontalImageScrollBinding + ) { + itemView.setProperties( + horizontalImageScrollData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/LargeBannerWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/LargeBannerWidgetVH.kt new file mode 100644 index 0000000000..39b606f553 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/LargeBannerWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LargeBannerWidgetLayoutBinding +import com.navi.naviwidgets.models.LargeBannerWidget +import com.navi.naviwidgets.widgets.LargeBannerWidgetLayout + +class LargeBannerWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(viewDataBinding.root) { + + override fun bind( + model: LargeBannerWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is LargeBannerWidgetLayout) { + itemView.update( + widgetData = model, + binding = viewDataBinding as LargeBannerWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { /*No-op*/ + } + +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatTypingStatusVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatTypingStatusVH.kt new file mode 100644 index 0000000000..d2e47f56a7 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatTypingStatusVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutNaviChatTypingStatusBinding +import com.navi.naviwidgets.models.response.NaviChatTypingStatusWidget +import com.navi.naviwidgets.widgets.NaviChatTypingStatusLayout + +class NaviChatTypingStatusVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: NaviChatTypingStatusWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is NaviChatTypingStatusLayout) { + itemView.update( + info = model, + binding = (viewDataBinding as LayoutNaviChatTypingStatusBinding), + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*no-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*no-op*/ + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatViewHolderFactoryImpl.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatViewHolderFactoryImpl.kt index 88ef4cd295..fda59cc1bc 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatViewHolderFactoryImpl.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/NaviChatViewHolderFactoryImpl.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.naviwidgets.viewholder import androidx.databinding.ViewDataBinding @@ -29,50 +30,64 @@ class NaviChatViewHolderFactoryImpl( R.layout.layout_navi_chat_message_with_action_item_list private val NAVI_CHAT_CONVERSATION_STATUS_WIDGET = R.layout.layout_chat_conversation_status private val NAVI_CHAT_LOADER_WIDGET = R.layout.layout_navi_chat_load_state - private val NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET = R.layout.layout_navi_chat_sent_message_with_attachment - private val NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET = R.layout.layout_navi_chat_received_message_with_attachment + private val NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET = + R.layout.layout_navi_chat_sent_message_with_attachment + private val NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET = + R.layout.layout_navi_chat_received_message_with_attachment private val UNKNOWN_WIDGET = R.layout.dummy_content_view - private val NAVI_CHAT_MESSAGE_WITH_DEEP_LINK = R.layout.layout_navi_chat_message_with_deeplink + private val NAVI_CHAT_MESSAGE_WITH_DEEP_LINK = + R.layout.layout_navi_chat_message_with_deeplink + private val NAVI_CHAT_TYPING_STATUS_WIDGET = R.layout.layout_navi_chat_typing_status } - override fun type(item: NaviBaseAdapterModel): Int = when (item) { - is NaviChatMessageWidget -> if (senderId == item.senderId && senderType == item.senderType) { - NAVI_CHAT_SENT_MESSAGE_WIDGET - } else { - NAVI_CHAT_RECEIVED_MESSAGE_WIDGET + override fun type(item: NaviBaseAdapterModel): Int = + when (item) { + is NaviChatMessageWidget -> + if (senderId == item.senderId && senderType == item.senderType) { + NAVI_CHAT_SENT_MESSAGE_WIDGET + } else { + NAVI_CHAT_RECEIVED_MESSAGE_WIDGET + } + is NaviChatMessageWithItemListWidget -> NAVI_CHAT_MESSAGE_WITH_ITEM_LIST + is NaviChatMessageItemWidget -> NAVI_CHAT_MESSAGE_ITEM_WIDGET + is NaviChatActionMessageItemWidget -> NAVI_CHAT_MESSAGE_ACTION_ITEM_WIDGET + is NaviChatMessageWithActionItemListWidget -> NAVI_CHAT_MESSAGE_WITH_ACTION_ITEM_LIST + is NaviChatConversationStatusWidget -> NAVI_CHAT_CONVERSATION_STATUS_WIDGET + is NaviChatLoaderWidget -> NAVI_CHAT_LOADER_WIDGET + is GenericWidgetDataInfo -> UNKNOWN_WIDGET + is NaviChatMessageWithDeepLinkWidget -> NAVI_CHAT_MESSAGE_WITH_DEEP_LINK + is NaviChatFileAttachmentWidget -> + if (senderId == item.senderId && senderType == item.senderType) { + NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET + } else { + NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET + } + is NaviChatTypingStatusWidget -> NAVI_CHAT_TYPING_STATUS_WIDGET + else -> Int.MAX_VALUE } - is NaviChatMessageWithItemListWidget -> NAVI_CHAT_MESSAGE_WITH_ITEM_LIST - is NaviChatMessageItemWidget -> NAVI_CHAT_MESSAGE_ITEM_WIDGET - is NaviChatActionMessageItemWidget -> NAVI_CHAT_MESSAGE_ACTION_ITEM_WIDGET - is NaviChatMessageWithActionItemListWidget -> NAVI_CHAT_MESSAGE_WITH_ACTION_ITEM_LIST - is NaviChatConversationStatusWidget -> NAVI_CHAT_CONVERSATION_STATUS_WIDGET - is NaviChatLoaderWidget -> NAVI_CHAT_LOADER_WIDGET - is GenericWidgetDataInfo -> UNKNOWN_WIDGET - is NaviChatMessageWithDeepLinkWidget -> NAVI_CHAT_MESSAGE_WITH_DEEP_LINK - is NaviChatFileAttachmentWidget -> if (senderId == item.senderId && senderType == item.senderType) { - NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET - } else { - NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET - } - else -> Int.MAX_VALUE - } override fun create(parent: ViewDataBinding, viewType: Int): BaseViewHolder = when (viewType) { NAVI_CHAT_RECEIVED_MESSAGE_WIDGET -> NaviChatReceivedMessageVH(viewDataBinding = parent) NAVI_CHAT_SENT_MESSAGE_WIDGET -> NaviChatSentMessageVH(viewDataBinding = parent) - NAVI_CHAT_MESSAGE_WITH_ITEM_LIST -> NaviChatMessageWithItemListVH(viewDataBinding = parent) + NAVI_CHAT_MESSAGE_WITH_ITEM_LIST -> + NaviChatMessageWithItemListVH(viewDataBinding = parent) NAVI_CHAT_MESSAGE_ITEM_WIDGET -> NaviChatMessageItemVH(viewDataBinding = parent) - NAVI_CHAT_MESSAGE_ACTION_ITEM_WIDGET -> NaviChatMessageActionItemVH(viewDataBinding = parent) - NAVI_CHAT_MESSAGE_WITH_ACTION_ITEM_LIST -> NaviChatMessageWithActionListVH( - viewDataBinding = parent - ) - NAVI_CHAT_CONVERSATION_STATUS_WIDGET -> NaviChatConversationStatusVH(viewDataBinding = parent) + NAVI_CHAT_MESSAGE_ACTION_ITEM_WIDGET -> + NaviChatMessageActionItemVH(viewDataBinding = parent) + NAVI_CHAT_MESSAGE_WITH_ACTION_ITEM_LIST -> + NaviChatMessageWithActionListVH(viewDataBinding = parent) + NAVI_CHAT_CONVERSATION_STATUS_WIDGET -> + NaviChatConversationStatusVH(viewDataBinding = parent) NAVI_CHAT_LOADER_WIDGET -> NaviChatLoaderVH(viewDataBinding = parent) NAVI_CHAT_MESSAGE_WITH_DEEP_LINK -> NaviChatDeepLinkWidgetVH(viewDataBinding = parent) - NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET -> NaviChatSentMessageWithAttachmentVH(viewDataBinding = parent) - NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET -> NaviChatReceivedMessageWithAttachmentVH(viewDataBinding = parent) + NAVI_CHAT_SENT_MESSAGE_WITH_ATTACHMENT_WIDGET -> + NaviChatSentMessageWithAttachmentVH(viewDataBinding = parent) + NAVI_CHAT_RECEIVED_MESSAGE_WITH_ATTACHMENT_WIDGET -> + NaviChatReceivedMessageWithAttachmentVH(viewDataBinding = parent) + NAVI_CHAT_TYPING_STATUS_WIDGET -> NaviChatTypingStatusVH(viewDataBinding = parent) UNKNOWN_WIDGET -> UnknownWidgetVH(view = parent) else -> UnknownWidgetVH(view = parent) - } as BaseViewHolder -} \ No newline at end of file + } + as BaseViewHolder +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsCardWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsCardWidgetVH.kt new file mode 100644 index 0000000000..af36cf1fd9 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsCardWidgetVH.kt @@ -0,0 +1,40 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PolicyDetailsCardWidgetLayoutBinding +import com.navi.naviwidgets.models.response.PolicyDetailsCardWidget +import com.navi.naviwidgets.widgets.PolicyDetailsCardWidgetLayout + +class PolicyDetailsCardWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} + + override fun onRecycled() {} + override fun bind( + model: PolicyDetailsCardWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is PolicyDetailsCardWidgetLayout && + viewDataBinding is PolicyDetailsCardWidgetLayoutBinding + ) { + itemView.setProperties( + widgetData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsWidgetVH.kt new file mode 100644 index 0000000000..537224dea5 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PolicyDetailsWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PolicyDetailsWidgetBinding +import com.navi.naviwidgets.models.response.PolicyDetailsWidget +import com.navi.naviwidgets.widgets.PolicyDetailsWidgetLayout + +class PolicyDetailsWidgetVH(private val viewDataBinding: ViewDataBinding): + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: PolicyDetailsWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if(itemView is PolicyDetailsWidgetLayout && viewDataBinding is PolicyDetailsWidgetBinding) { + itemView.setProperties( + infoData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) { + } + + override fun bindWidgetStateChanged(payload: Any?) { + } + + override fun onRecycled() { + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PostDisbursalSuccessWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PostDisbursalSuccessWidgetVH.kt new file mode 100644 index 0000000000..a2edb18ac3 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/PostDisbursalSuccessWidgetVH.kt @@ -0,0 +1,35 @@ +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PostDisbursalSuccessWidgetLayoutBinding +import com.navi.naviwidgets.models.PostDisbursalSuccessWidget +import com.navi.naviwidgets.widgets.PostDisbursalSuccessWidgetLayout + +class PostDisbursalSuccessWidgetVH(private val viewBinding: ViewDataBinding) : + BaseViewHolder(view = viewBinding.root) { + + override fun bind( + model: PostDisbursalSuccessWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if (itemView is PostDisbursalSuccessWidgetLayout) + itemView.update( + widgetData = model, + binding = viewBinding as PostDisbursalSuccessWidgetLayoutBinding, + widgetCallback = widgetCallback, + position = position + ) + } + + override fun bindError(errorData: Any?) { + } + + override fun bindWidgetStateChanged(payload: Any?) { + } + + override fun onRecycled() { + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductBenefitsGridWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductBenefitsGridWidgetVH.kt new file mode 100644 index 0000000000..7ece456c81 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductBenefitsGridWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutProductBenefitsGridWidgetBinding +import com.navi.naviwidgets.models.response.ProductBenefitsGridWidget +import com.navi.naviwidgets.widgets.ProductBenefitsGridWidgetLayout + +class ProductBenefitsGridWidgetVH(private val viewDataBinding: ViewDataBinding) : BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: ProductBenefitsGridWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is ProductBenefitsGridWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutProductBenefitsGridWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductClickCardWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductClickCardWidgetVH.kt new file mode 100644 index 0000000000..d613097468 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductClickCardWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ProductClickCardWidgetBinding +import com.navi.naviwidgets.models.response.ProductClickCardWidget +import com.navi.naviwidgets.widgets.ProductClickCardWidgetLayout + +class ProductClickCardWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} + + override fun onRecycled() {} + + override fun bind( + model: ProductClickCardWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is ProductClickCardWidgetLayout && + viewDataBinding is ProductClickCardWidgetBinding + ) { + itemView.setProperties( + widgetData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductIntroWithButtonWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductIntroWithButtonWidgetVH.kt new file mode 100644 index 0000000000..dd946efdf5 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ProductIntroWithButtonWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ProductIntroWithButtonWidgetLayoutBinding +import com.navi.naviwidgets.models.response.ProductIntroWithButtonWidget +import com.navi.naviwidgets.widgets.ProductIntroWithButtonWidgetLayout + +class ProductIntroWithButtonWidgetVH(private val viewDataBinding: ViewDataBinding) : BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: ProductIntroWithButtonWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is ProductIntroWithButtonWidgetLayout) { + itemView.update( + binding = (viewDataBinding as ProductIntroWithButtonWidgetLayoutBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SliderWithDotsIndicatorVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SliderWithDotsIndicatorVH.kt new file mode 100644 index 0000000000..12633ec2f7 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/SliderWithDotsIndicatorVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutSliderWithDotsIndicatorWidgetBinding +import com.navi.naviwidgets.models.response.SliderWithDotIndicatorWidget +import com.navi.naviwidgets.widgets.SliderWithDotIndicatorsWidgetLayout + +class SliderWithDotsIndicatorVH(private val viewDataBinding: ViewDataBinding) : BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: SliderWithDotIndicatorWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is SliderWithDotIndicatorsWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutSliderWithDotsIndicatorWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TitleDescIconCtaWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TitleDescIconCtaWidgetVH.kt new file mode 100644 index 0000000000..97b7687bbc --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TitleDescIconCtaWidgetVH.kt @@ -0,0 +1,41 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.TitleDescIconCtaWidgetLayoutBinding +import com.navi.naviwidgets.models.response.TitleDescIconCtaWidget +import com.navi.naviwidgets.widgets.TitleDescIconCtaWidgetLayout + +class TitleDescIconCtaWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: TitleDescIconCtaWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is TitleDescIconCtaWidgetLayout && + viewDataBinding is TitleDescIconCtaWidgetLayoutBinding + ) { + itemView.setProperties( + tdicInfoWidgetData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) {} + + override fun bindWidgetStateChanged(payload: Any?) {} + + override fun onRecycled() {} +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TrustedBuilderWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TrustedBuilderWidgetVH.kt new file mode 100644 index 0000000000..7e477ba05b --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TrustedBuilderWidgetVH.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutTrustedBuildersWidgetBinding +import com.navi.naviwidgets.models.response.TrustedBuilderWidget +import com.navi.naviwidgets.widgets.TrustedBuildersWidgetLayout + +class TrustedBuilderWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: TrustedBuilderWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is TrustedBuildersWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutTrustedBuildersWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TwoInfoCardsWithTitleWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TwoInfoCardsWithTitleWidgetVH.kt new file mode 100644 index 0000000000..338e5e2a2b --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/TwoInfoCardsWithTitleWidgetVH.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutTwoIfnoCardsWithTitleWidgetBinding +import com.navi.naviwidgets.models.response.TwoInfoCardsWithTitleWidget +import com.navi.naviwidgets.widgets.TwoInfoCardsWithTitleWidgetLayout + +class TwoInfoCardsWithTitleWidgetVH(private val viewDataBinding: ViewDataBinding) : +BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: TwoInfoCardsWithTitleWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is TwoInfoCardsWithTitleWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutTwoIfnoCardsWithTitleWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/UnderstandProcessVideoVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/UnderstandProcessVideoVH.kt new file mode 100644 index 0000000000..f809e3db76 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/UnderstandProcessVideoVH.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutUnderstandProcessVideoWidgetBinding +import com.navi.naviwidgets.models.response.UnderstandProcessVideoWidget +import com.navi.naviwidgets.widgets.UnderstandProcessVideoWidgetLayout + +class UnderstandProcessVideoVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + + override fun bind( + model: UnderstandProcessVideoWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int, + ) { + if (itemView is UnderstandProcessVideoWidgetLayout) { + itemView.update( + binding = (viewDataBinding as LayoutUnderstandProcessVideoWidgetBinding), + widgetData = model, + widgetCallback = widgetCallback, + position = position + ) + } + } + + override fun bindError(errorData: Any?) { + /*No-op*/ + } + + override fun bindWidgetStateChanged(payload: Any?) { + /*No-op*/ + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/VerticalCheckpointWidgetVH.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/VerticalCheckpointWidgetVH.kt new file mode 100644 index 0000000000..518fd048ed --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/VerticalCheckpointWidgetVH.kt @@ -0,0 +1,34 @@ +package com.navi.naviwidgets.viewholder + +import androidx.databinding.ViewDataBinding +import com.navi.naviwidgets.VerticalCheckpointWidgetLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.VerticalCheckpointLayoutBinding +import com.navi.naviwidgets.models.response.VerticalCheckpointWidget + +class VerticalCheckpointWidgetVH(private val viewDataBinding: ViewDataBinding) : + BaseViewHolder(view = viewDataBinding.root) { + override fun bind( + model: VerticalCheckpointWidget, + widgetCallback: WidgetCallback, + position: Int, + totalItems: Int + ) { + if ( + itemView is VerticalCheckpointWidgetLayout && + viewDataBinding is VerticalCheckpointLayoutBinding + ) { + itemView.setProperties( + verticalCheckpointData = model, + widgetCallback = widgetCallback, + binding = viewDataBinding + ) + } + } + + override fun bindError(errorData: Any?) { + } + + override fun bindWidgetStateChanged(payload: Any?) { + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt index 5cb99b2121..15555d48dc 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/viewholder/ViewHolderFactoryImpl.kt @@ -61,6 +61,8 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory private val CUSTOMER_RATING_WIDGET = R.layout.layout_customer_rating private val TEXT_WITH_BACKGROUND_WIDGET = R.layout.text_with_background_widget_layout private val HOME_PRODUCT_WIDGET = R.layout.home_product_widget_layout + private val HOME_STU_PRODUCT_WIDGET = R.layout.home_stu_product_widget_layout + private val HOME_STU_PRODUCT_MINI_WIDGET = R.layout.home_stu_product_mini_widget_layout private val SQUARE_PRODUCT_WIDGET = R.layout.square_product_widget_layout private val PAYMENT_ACTION_WIDGET = R.layout.payment_action_widget_layout private val DETAILS_WIDGET = R.layout.details_widget_layout @@ -108,6 +110,26 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory private val REPAYMENT_OPTIONS_WIDGET = R.layout.layout_repayment_options private val PAYMENT_TOOLTIP_WIDGET = R.layout.layout_payment_tooltip private val PAYMENT_LABEL_WIDGET = R.layout.layout_payment_label + private val EXPANDABLE_FAQS_WIDGET = R.layout.expandable_faqs_widget_layout + private val TITLE_DESC_ICON_CTA_WIDGET = R.layout.title_desc_icon_cta_widget_layout + private val HORIZONTAL_IMAGE_SCROLL_WIDGET = R.layout.horizontal_image_scroll + private val POLICY_DETAILS_CARD_WIDGET = R.layout.policy_details_card_widget_layout + private val PRODUCT_CLICK_CARD_WIDGET = R.layout.product_click_card_widget + private val POST_DISBURSAL_SUCCESS_WIDGET = R.layout.post_disbursal_success_widget_layout + private val LARGE_BANNER_WIDGET = R.layout.large_banner_widget_layout + private val CENTERED_TITLE_SUBTITLE_DESC_WIDGET = R.layout.centred_title_subtitle_desc_widget + private val POLICY_DETAILS_WIDGET = R.layout.policy_details_widget + private val VERTICAL_CHECKPOINT_WIDGET = R.layout.vertical_checkpoint_layout + private val FOOTER_WITH_TITLE_AND_BUTTON = R.layout.footer_with_title_and_button + private val PRODUCT_INTRO_WITH_BUTTON = R.layout.product_intro_with_button_widget_layout + private val SLIDER_WITH_DOTS_INDICATOR_WIDGET = + R.layout.layout_slider_with_dots_indicator_widget + private val APPLIED_USER_COUNT_WIDGET = R.layout.layout_applied_user_count_widget + private val UNDERSTAND_PROCESS_VIDEO_WIDGET = + R.layout.layout_understand_process_video_widget + private val PRODUCT_BENEFITS_GRID_WIDGET = R.layout.layout_product_benefits_grid_widget + private val TRUSTED_BUILDERS_WIDGET = R.layout.layout_trusted_builders_widget + private val TWO_INFO_CARDS_WITH_TITLE_WIDGET = R.layout.layout_two_ifno_cards_with_title_widget // Incase unknown/un-registered widget comes we need to handle that private val GENERIC_WIDGET = R.layout.dummy_content_view @@ -195,6 +217,28 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory is PaymentLabelWidget -> PAYMENT_LABEL_WIDGET is ElevatedIconWidgetData -> ELEVATED_ICON_WIDGET is TextWithUnderlineWidget -> TEXT_WITH_UNDERLINE_WIDGET + is HomeStuProductWidget -> HOME_STU_PRODUCT_WIDGET + is HomeStuProductMiniWidget -> HOME_STU_PRODUCT_MINI_WIDGET + is TitleDescIconCtaWidget -> TITLE_DESC_ICON_CTA_WIDGET + is HorizontalImageScrollWidget -> HORIZONTAL_IMAGE_SCROLL_WIDGET + is PolicyDetailsCardWidget -> POLICY_DETAILS_CARD_WIDGET + is ProductClickCardWidget -> PRODUCT_CLICK_CARD_WIDGET + is ExpandableFaqWidget -> EXPANDABLE_FAQS_WIDGET + is CentredTitleSubtitleDescWidget -> CENTERED_TITLE_SUBTITLE_DESC_WIDGET + is PolicyDetailsWidget -> POLICY_DETAILS_WIDGET + is VerticalCheckpointWidget -> VERTICAL_CHECKPOINT_WIDGET + is FooterWithTitleAndButton -> FOOTER_WITH_TITLE_AND_BUTTON + is PostDisbursalSuccessWidget -> POST_DISBURSAL_SUCCESS_WIDGET + is LargeBannerWidget -> LARGE_BANNER_WIDGET + is SingleImageWidget -> SINGLE_IMAGE_WIDGET + is ProductIntroWithButtonWidget -> PRODUCT_INTRO_WITH_BUTTON + is SliderWithDotIndicatorWidget -> SLIDER_WITH_DOTS_INDICATOR_WIDGET + is AppliedUserCountWidget -> APPLIED_USER_COUNT_WIDGET + is UnderstandProcessVideoWidget -> UNDERSTAND_PROCESS_VIDEO_WIDGET + is ProductBenefitsGridWidget -> PRODUCT_BENEFITS_GRID_WIDGET + is TrustedBuilderWidget -> TRUSTED_BUILDERS_WIDGET + is TwoInfoCardsWithTitleWidget -> TWO_INFO_CARDS_WITH_TITLE_WIDGET + // Default case, add all widgets above this is GenericWidgetDataInfo -> GENERIC_WIDGET else -> Int.MAX_VALUE @@ -247,6 +291,8 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory UnknownWidgetVH(parent) // Incase unknown widget comes we need to handle that HOME_PRODUCT_WIDGET -> HomeProductWidgetVH(parent) SQUARE_PRODUCT_WIDGET -> SquareProductWidgetVH(parent) + HOME_STU_PRODUCT_WIDGET -> HomeStuProductWidgetVH(parent) + HOME_STU_PRODUCT_MINI_WIDGET -> HomeStuProductMiniWidgetVH(parent) DETAILS_WIDGET -> DetailsWidgetVH(parent) SOCIAL_MEDIA_ADVERTISEMENT_WIDGET -> SocialMediaAdvertisementVH(parent) ELEVATED_ICON_WIDGET -> ElevatedIconWidgetVH(parent) @@ -283,6 +329,24 @@ class ViewHolderFactoryImpl : ViewHolderTypeFactory REPAYMENT_OPTIONS_WIDGET -> RepaymentOptionsWidgetVH(parent) PAYMENT_TOOLTIP_WIDGET -> PaymentTooltipWidgetVH(parent) PAYMENT_LABEL_WIDGET -> PaymentLabelWidgetVH(parent) + TITLE_DESC_ICON_CTA_WIDGET -> TitleDescIconCtaWidgetVH(parent) + HORIZONTAL_IMAGE_SCROLL_WIDGET -> HorizontalImageScrollVH(parent) + POLICY_DETAILS_CARD_WIDGET -> PolicyDetailsCardWidgetVH(parent) + PRODUCT_CLICK_CARD_WIDGET -> ProductClickCardWidgetVH(parent) + EXPANDABLE_FAQS_WIDGET -> ExpandableFaqWidgetVH(parent) + CENTERED_TITLE_SUBTITLE_DESC_WIDGET -> CentredTitleSubtitleDescWidgetVH(parent) + POLICY_DETAILS_WIDGET -> PolicyDetailsWidgetVH(parent) + VERTICAL_CHECKPOINT_WIDGET -> VerticalCheckpointWidgetVH(parent) + FOOTER_WITH_TITLE_AND_BUTTON -> FooterWithTitleAndButtonVH(parent) + POST_DISBURSAL_SUCCESS_WIDGET -> PostDisbursalSuccessWidgetVH(parent) + LARGE_BANNER_WIDGET -> LargeBannerWidgetVH(parent) + PRODUCT_INTRO_WITH_BUTTON -> ProductIntroWithButtonWidgetVH(parent) + SLIDER_WITH_DOTS_INDICATOR_WIDGET -> SliderWithDotsIndicatorVH(parent) + UNDERSTAND_PROCESS_VIDEO_WIDGET -> UnderstandProcessVideoVH(parent) + APPLIED_USER_COUNT_WIDGET -> AppliedUserCountWidgetVH(parent) + PRODUCT_BENEFITS_GRID_WIDGET -> ProductBenefitsGridWidgetVH(parent) + TRUSTED_BUILDERS_WIDGET -> TrustedBuilderWidgetVH(parent) + TWO_INFO_CARDS_WITH_TITLE_WIDGET -> TwoInfoCardsWithTitleWidgetVH(parent) else -> UnknownWidgetVH(parent) } as BaseViewHolder diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/views/ImageViewWidget.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/views/ImageViewWidget.kt index 1a95854206..d9d7fe817b 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/views/ImageViewWidget.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/views/ImageViewWidget.kt @@ -68,6 +68,7 @@ class ImageViewWidget(context: Context, attrs: AttributeSet?) : } data?.actionData?.let { cta -> setOnClickListener { + widgetCallback?.widgetAnalytics(data.metaData?.clickedData) widgetCallback?.onClick(cta) } } diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/views/NaviErrorPageView.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/views/NaviErrorPageView.kt new file mode 100644 index 0000000000..101f5d8033 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/views/NaviErrorPageView.kt @@ -0,0 +1,57 @@ +package com.navi.naviwidgets.views + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.databinding.DataBindingUtil +import com.navi.naviwidgets.R +import com.navi.naviwidgets.databinding.NaviErrorPageLayoutBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.NaviErrorPageWidget +import com.navi.naviwidgets.models.response.TextFieldData +import com.navi.naviwidgets.utils.NaviWidgetIconUtils + +class NaviErrorPageView(context: Context, attrs: AttributeSet? = null) : ConstraintLayout(context, attrs) { + private var binding: NaviErrorPageLayoutBinding + + var tag: String? = null + + init { + val inflater = LayoutInflater.from(context) + binding = DataBindingUtil.inflate(inflater, R.layout.navi_error_page_layout, this, true) + } + + fun setProperties( + callback: Callback, + naviErrorPageWidget: NaviErrorPageWidget = NaviErrorPageWidget( + TextFieldData(text = "Something went wrong"), + TextFieldData(text = "It appears we are facing trouble.\nPlease try again"), + TextFieldData(text = "Retry"), + NaviWidgetIconUtils.EXPIRED_POLICY_ICON + ) + ) { + naviErrorPageWidget.apply { + iconName?.let { + binding.icon.setImageResource(NaviWidgetIconUtils.getIconResourceId(it)) + } + title?.let { + binding.title.setTextFieldData(it) + } + subTitle?.let { + binding.subTitle.setTextFieldData(it) + } + buttonText?.let { + binding.button.setTextFieldData(it) + } + } + binding.button.setOnClickListener { + callback.onRetryClick(tag) + } + } + + interface Callback { + fun onRetryClick(tag: String?) + } + +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AdvertisementWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AdvertisementWidgetLayout.kt index 434e407efd..0748aa748c 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AdvertisementWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AdvertisementWidgetLayout.kt @@ -3,13 +3,14 @@ package com.navi.naviwidgets.widgets import android.content.Context import android.util.AttributeSet import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.design.utils.dpToPxInInt import com.navi.design.utils.parseColorSafe import com.navi.design.utils.setSpannableString import com.navi.naviwidgets.R import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.databinding.AdvertismentWidgetLayoutBinding import com.navi.naviwidgets.extensions.setCornerRadius -import com.navi.naviwidgets.extensions.setSpannableString +import com.navi.naviwidgets.extensions.setGradient import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.naviwidgets.models.response.AdvertisementWidget import com.navi.naviwidgets.models.response.UpcomingLoanDetail @@ -41,9 +42,23 @@ class AdvertisementWidgetLayout(context: Context, attributeSet: AttributeSet) : titleIcon.showWhenDataIsAvailable(imageUrl = widgetData.advertisementWidgetData?.header?.iconUrl) titleTv.showWhenDataIsAvailable(showText = widgetData.advertisementWidgetData?.header?.title) mainContent.setCornerRadius(resources.getDimension(R.dimen.dp_16)) - mainContent.setBackgroundColor(widgetData.advertisementWidgetData?.content?.bgColor.parseColorSafe()) + widgetData.advertisementWidgetData?.content?.bgColor?.let { + mainContent.setBackgroundColor(it.parseColorSafe()) + } ?: run { + widgetData.advertisementWidgetData?.content?.gradient?.let { + mainContent.setGradient(it) + } + } setViewConstraint(widgetData.advertisementWidgetData?.content?.topIcon?.gravity) - tagIcon.showWhenDataIsAvailable(widgetData.advertisementWidgetData?.content?.topIcon?.imageUrl) + widgetData.advertisementWidgetData?.content?.topIcon?.let { + it.height?.let { height -> + tagIcon.layoutParams.height = dpToPxInInt(height) + } + it.width?.let { width -> + tagIcon.layoutParams.width = dpToPxInInt(width) + } + tagIcon.showWhenDataIsAvailable(it.imageUrl) + } leadingIcon.showWhenDataIsAvailable(widgetData.advertisementWidgetData?.content?.imageUrl) description.setSpannableString(widgetData.advertisementWidgetData?.content?.description) offerText.setSpannableString(widgetData.advertisementWidgetData?.content?.offerData) diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AppliedUserCountWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AppliedUserCountWidgetLayout.kt new file mode 100644 index 0000000000..82f3be5b0c --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/AppliedUserCountWidgetLayout.kt @@ -0,0 +1,42 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutAppliedUserCountWidgetBinding +import com.navi.naviwidgets.models.response.AppliedUserCountWidget + +class AppliedUserCountWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LayoutAppliedUserCountWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: AppliedUserCountWidget + private var position = Int.MAX_VALUE + + fun update( + widgetData: AppliedUserCountWidget, + binding: LayoutAppliedUserCountWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + setProperties() + } + + private fun setProperties() { + binding.data = widgetData.appliedUserCountWidgetData + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/CentredTitleSubtitleDescWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/CentredTitleSubtitleDescWidgetLayout.kt new file mode 100644 index 0000000000..ef3c19c59f --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/CentredTitleSubtitleDescWidgetLayout.kt @@ -0,0 +1,35 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Private Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import android.widget.LinearLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.CentredTitleSubtitleDescWidgetBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.CentredTitleSubtitleDescWidget + +class CentredTitleSubtitleDescWidgetLayout @JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : LinearLayout(parentContext, attrs, defStyleAttr) { + fun setProperties( + widgetData: CentredTitleSubtitleDescWidget, + widgetCallback: WidgetCallback, + binding: CentredTitleSubtitleDescWidgetBinding + ) { + widgetData.widgetData()?.let { widgetData -> + binding.title.setTextFieldData(widgetData.title) + binding.subtitle.setTextFieldData(widgetData.subtitle) + binding.description.setTextFieldData(widgetData.description) + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ExpandableFaqWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ExpandableFaqWidgetLayout.kt new file mode 100644 index 0000000000..d098b7d990 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ExpandableFaqWidgetLayout.kt @@ -0,0 +1,40 @@ +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.naviwidgets.adapters.ExpandableFaqAdapter +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ExpandableFaqsWidgetLayoutBinding +import com.navi.naviwidgets.models.response.ExpandableFaqWidget +import com.navi.naviwidgets.models.response.FaqsData +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class ExpandableFaqWidgetLayout +@JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + private lateinit var binding: ExpandableFaqsWidgetLayoutBinding + + fun setProperties( + expandableFaqsListData: ExpandableFaqWidget, + widgetCallback: WidgetCallback?, + binding: ExpandableFaqsWidgetLayoutBinding + ) { + this.binding = binding + setWidgetLayoutParams(expandableFaqsListData.widgetLayoutParams, binding.root) + setFaqsListItems(expandableFaqsListData.expandableFAQsWidgetBody?.faqsList, widgetCallback) + } + + private fun setFaqsListItems( + expandableFAQsWidgetBody: List?, + widgetCallback: WidgetCallback? + ) { + val faqAdapter = ExpandableFaqAdapter(widgetCallback) + faqAdapter.setData(expandableFAQsWidgetBody ?: emptyList()) + binding.rvFaqs.adapter = faqAdapter + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FooterWithTitleAndButtonLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FooterWithTitleAndButtonLayout.kt new file mode 100644 index 0000000000..361f1ba748 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FooterWithTitleAndButtonLayout.kt @@ -0,0 +1,59 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.FooterWithTitleAndButtonBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.FooterWithTitleAndButton +import com.navi.naviwidgets.models.response.FooterWithTitleAndButtonBody +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class FooterWithTitleAndButtonLayout@JvmOverloads constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + private lateinit var binding: FooterWithTitleAndButtonBinding + + fun setProperties( + infoData : FooterWithTitleAndButton?, + widgetCallback: WidgetCallback?, + binding: FooterWithTitleAndButtonBinding + ) { + this.binding = binding + + layoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + + setWidgetLayoutParams(infoData?.widgetLayoutParams, binding.root) + + val footerWithTitleAndButtonInfo: FooterWithTitleAndButtonBody? = infoData?.widgetData() + + footerWithTitleAndButtonInfo?.let { + + // Footer Title + binding.title.setTextFieldData(footerWithTitleAndButtonInfo.title) + + // Footer Button + footerWithTitleAndButtonInfo.button?.let { footerBtn -> + + binding.footerButton.setTextFieldData(footerBtn.title) + binding.footerButton.setOnClickListener { + footerBtn.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + } + } + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FreeInsuranceSuccessWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FreeInsuranceSuccessWidgetLayout.kt new file mode 100644 index 0000000000..3ed764de0a --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/FreeInsuranceSuccessWidgetLayout.kt @@ -0,0 +1,93 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.airbnb.lottie.LottieAnimationView +import com.airbnb.lottie.LottieCompositionFactory +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.FreeInsuranceSuccessWidgetBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.interfaces.FreeInsuranceSuccessWidgetInfo +import com.navi.naviwidgets.utils.NaviWidgetIconUtils +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class FreeInsuranceSuccessWidgetLayout +@JvmOverloads +constructor(context: Context, attributes: AttributeSet? = null) : + ConstraintLayout(context, attributes) { + + private var binding: FreeInsuranceSuccessWidgetBinding? = null + private var info: FreeInsuranceSuccessWidgetInfo? = null + private var widgetCallback: WidgetCallback? = null + + fun update( + binding: FreeInsuranceSuccessWidgetBinding, + info: FreeInsuranceSuccessWidgetInfo, + widgetCallback: WidgetCallback + ) { + this.binding = binding + this.info = info + this.widgetCallback = widgetCallback + setProperties() + } + + fun setProperties() { + + binding?.apply { + if(info?.widgetLayoutParams()?.gradient != null) { + setWidgetLayoutParams(info?.widgetLayoutParams(), rootCl) + } else { + setWidgetLayoutParams(info?.widgetLayoutParams()?.copy(gradient = info?.backgroundGradient()), rootCl) + } + title.setTextFieldData(info?.headerText()) + description.setTextFieldData(info?.descriptionText()) + footerText.setTextFieldData(info?.footerText()) + NaviWidgetIconUtils.getImageFromIconCode(info?.iconCode()).takeIf { it != -1 }?.let { + iconSuccess.setImageResource(it) + } + setLottieData(info?.successAnimationId(),successAnimation) + setLottieData(info?.diseaseAnimationId(),diseaseAnimation) + rootCl.setOnClickListener { + info?.cta()?.let { ctaData -> + widgetCallback?.onClick(ctaData) + } + info?.metaData()?.let { + widgetCallback?.widgetAnalytics(it.clickedData) + } + } + } + } + + private fun setLottieData( + animationId: String?, + lottieView: LottieAnimationView + ) { + context?.let { context -> + if (animationId != null) { + var rawFileResourceId: Int = resources.getIdentifier( + animationId, + "raw", + context.packageName + ) + if (rawFileResourceId != -1) { + lottieView.removeAllAnimatorListeners() + LottieCompositionFactory.fromRawRes(context, rawFileResourceId) + .addListener { + lottieView.setComposition(it) + lottieView.playAnimation() + } + } + } + } + + } + +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeProductWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeProductWidgetLayout.kt index 6c0ebf62d8..902ecec31d 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeProductWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeProductWidgetLayout.kt @@ -8,6 +8,7 @@ import android.view.View import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.databinding.DataBindingUtil import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver @@ -76,9 +77,12 @@ class HomeProductWidgetLayout(context: Context, attributeSet: AttributeSet) : widgetCallback.onClick(actionData) } } ?: run { - actionBtn.visibility = View.INVISIBLE + if (widgetData.homeProductWidgetData?.productDetails?.showOnlySubProducts == true) { + actionBtn.isVisible = false + } else { + actionBtn.visibility = View.INVISIBLE + } } - productImage.showWhenDataIsAvailable(widgetData.homeProductWidgetData?.productDetails?.imageUrl) widgetData.homeProductWidgetData?.productDetails?.padding?.let { productImage.setPadding( @@ -107,6 +111,8 @@ class HomeProductWidgetLayout(context: Context, attributeSet: AttributeSet) : productStrategy.visibility = View.GONE } setLabelData() + divider.isVisible = + widgetData.homeProductWidgetData?.productDetails?.showOnlySubProducts != true } widgetData.homeProductWidgetData?.subProducts?.let { binding.subProducts.visibility = View.VISIBLE diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductMiniWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductMiniWidgetLayout.kt new file mode 100644 index 0000000000..1b2ae9e80a --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductMiniWidgetLayout.kt @@ -0,0 +1,77 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.parseColorSafe +import com.navi.design.utils.setSpannableString +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HomeStuProductMiniWidgetLayoutBinding +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.response.HomeStuProductMiniWidget + +class HomeStuProductMiniWidgetLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: HomeStuProductMiniWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + + private var widgetPosition: Int = Int.MAX_VALUE + private lateinit var widgetData: HomeStuProductMiniWidget + + fun update( + widgetData: HomeStuProductMiniWidget, + binding: HomeStuProductMiniWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + with(binding) { + tvTitle.setSpannableString(widgetData.homeStuProductMiniWidgetData?.title) + widgetData.homeStuProductMiniWidgetData?.bgColor?.let { + productCard.setBackgroundColor(it.parseColorSafe()) + } + widgetData.homeStuProductMiniWidgetData?.actionData?.let { actionData -> + binding.productCard.setOnClickListener { widgetCallback.onClick(actionData) } + } + + ivLeftIcon.showWhenDataIsAvailable(widgetData.homeStuProductMiniWidgetData?.leftIconUrl) + widgetData.homeStuProductMiniWidgetData?.leftPadding?.let { + ivLeftIcon.setPadding( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + ivRightIcon.showWhenDataIsAvailable( + widgetData.homeStuProductMiniWidgetData?.rightIconUrl + ) + widgetData.homeStuProductMiniWidgetData?.rightPadding?.let { + ivRightIcon.setPadding( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductWidgetLayout.kt new file mode 100644 index 0000000000..2bfc11faf0 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HomeStuProductWidgetLayout.kt @@ -0,0 +1,100 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.design.utils.dpToPxInInt +import com.navi.design.utils.parseColorSafe +import com.navi.design.utils.setSpannableString +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HomeStuProductWidgetLayoutBinding +import com.navi.naviwidgets.extensions.setGradient +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.response.HomeStuProductWidget + +class HomeStuProductWidgetLayout(context: Context, attributeSet: AttributeSet) : + ConstraintLayout(context, attributeSet) { + + private lateinit var binding: HomeStuProductWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + private lateinit var widgetData: HomeStuProductWidget + + fun update( + widgetData: HomeStuProductWidget, + binding: HomeStuProductWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + with(binding) { + titleTv.showWhenDataIsAvailable( + showText = widgetData.homeProductWidgetData?.header?.title + ) + iconIv.showWhenDataIsAvailable( + imageUrl = widgetData.homeProductWidgetData?.header?.iconUrl + ) + widgetData.homeProductWidgetData?.productDetails?.gradient?.let { + productCard.setGradient(it) + } + productTitle.setSpannableString(widgetData.homeProductWidgetData?.productDetails?.title) + productLottie.showWhenDataIsAvailable( + widgetData.homeProductWidgetData?.productDetails?.lottieFile + ) + productSubtitle.setSpannableString( + widgetData.homeProductWidgetData?.productDetails?.subtitle + ) + widgetData.homeProductWidgetData?.productDetails?.bgColor?.let { + productCard.setBackgroundColor(it.parseColorSafe()) + } + widgetData.homeProductWidgetData?.productDetails?.actionData?.let { actionData -> + actionBtn.visibility = View.VISIBLE + actionBtn.setProperties(actionData, widgetCallback) + binding.productCard.setOnClickListener { widgetCallback.onClick(actionData) } + } + ?: run { actionBtn.visibility = View.INVISIBLE } + + productImage.showWhenDataIsAvailable( + widgetData.homeProductWidgetData?.productDetails?.imageUrl + ) + widgetData.homeProductWidgetData?.productDetails?.padding?.let { + productImage.setPadding( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + widgetData.homeProductWidgetData?.productDetails?.lottiePadding?.let { + productLottie.setPadding( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + widgetData.homeProductWidgetData?.productStrategy?.let { + it.bgColor?.let { bgColor -> + productStrategy.setBackgroundColor(bgColor.parseColorSafe()) + } + it.item?.let { style -> productStrategy.setSpannableString(style) } + } + ?: run { productStrategy.visibility = View.GONE } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HorizontalImageScrollWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HorizontalImageScrollWidgetLayout.kt new file mode 100644 index 0000000000..e61f60a9f8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/HorizontalImageScrollWidgetLayout.kt @@ -0,0 +1,73 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.databinding.DataBindingUtil +import com.navi.naviwidgets.R +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.HorizontalImageScrollBinding +import com.navi.naviwidgets.databinding.ImageCardHolderLayoutBinding +import com.navi.naviwidgets.extensions.getScreenWidth +import com.navi.naviwidgets.models.response.HorizontalImageScrollWidget +import com.navi.naviwidgets.models.response.ItemData +import com.navi.naviwidgets.utils.loadUrlIntoImageView +import com.navi.naviwidgets.utils.setWidgetLayoutParams +import kotlin.math.roundToInt + +class HorizontalImageScrollWidgetLayout +@JvmOverloads +constructor( + parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + private lateinit var binding: HorizontalImageScrollBinding + private val defaultItemsOnScreen = 2.5f + + fun setProperties( + horizontalImageScrollData: HorizontalImageScrollWidget, + widgetCallback: WidgetCallback?, + binding: HorizontalImageScrollBinding + ) { + this.binding = binding + setWidgetLayoutParams(horizontalImageScrollData.widgetLayoutParams(), binding.root) + val imgWidth = getItemWidth(horizontalImageScrollData.widgetData()?.onScreenItemCount) + this.binding.apply { + horizontalImageScrollData.widgetData()?.itemList?.forEach { + val imageView = getImageItemView(it, imgWidth) + binding.scrollviewLl.addView(imageView) + } + } + } + + private fun getImageItemView(data: ItemData?, imgWidth: Int): View { + val itemViewBinding = + DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.image_card_holder_layout, + binding.horizontalScrollview, + false + ) + val layoutParams = MarginLayoutParams(imgWidth, LayoutParams.WRAP_CONTENT) + itemViewBinding.root.layoutParams = layoutParams + data?.url?.let { loadUrlIntoImageView(context, it, itemViewBinding.itemImage) } + return itemViewBinding.root + } + + private fun getItemWidth(visibleItemsOnScreen: Float?): Int { + val screenWidth = + getScreenWidth().toDouble() - resources.getDimensionPixelSize(R.dimen.dp_8) + return (screenWidth / ((visibleItemsOnScreen ?: defaultItemsOnScreen).toDouble())) + .roundToInt() + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ImageCarousalView.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ImageCarousalView.kt index 046bc44dfa..4497cf195f 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ImageCarousalView.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ImageCarousalView.kt @@ -14,6 +14,7 @@ import android.os.Handler import android.util.AttributeSet import android.view.View import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent @@ -100,6 +101,14 @@ class ImageCarousalView @JvmOverloads constructor( titleTv.setSpannableString(it) } } + if (widgetData.widgetData?.title.isNull() && widgetData.widgetData?.titleV2.isNull()) { + titleTv.isVisible = false + val layoutParams = recycleView.layoutParams as? MarginLayoutParams + layoutParams?.setMargins( + 0, 0, 0, 0 + ) + recycleView.layoutParams = layoutParams + } iconIv.showWhenDataIsAvailable(imageUrl = widgetData.widgetData?.iconUrl) widgetData.widgetData?.label?.bgColor?.let { label.background = getNaviDrawable( diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/LargeBannerWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/LargeBannerWidgetLayout.kt new file mode 100644 index 0000000000..e2a10dd040 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/LargeBannerWidgetLayout.kt @@ -0,0 +1,134 @@ +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.graphics.Color +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.airbnb.lottie.LottieAnimationView +import com.navi.base.model.NaviWidgetClickWithActionData +import com.navi.base.utils.isNotNull +import com.navi.design.utils.* +import com.navi.naviwidgets.R +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LargeBannerWidgetLayoutBinding +import com.navi.naviwidgets.extensions.isValidHexColor +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.LargeBannerWidget + + +class LargeBannerWidgetLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LargeBannerWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + private var bannerWidget: LargeBannerWidget? = null + + fun update( + widgetData: LargeBannerWidget, + binding: LargeBannerWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.bannerWidget = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.widgetPosition = position + setProperties() + } + + private fun setProperties() { + binding.apply { + bannerWidget?.widgetData?.let { data -> + title.text = data.title?.text?.spannedText( + context = context, + span = data.title.span + ) + subTitle.text = data.subtitle?.text?.spannedText( + context = context, + span = data.subtitle.span + ) + image.showWhenDataIsAvailable(data.imageUrl) + if (isValidHexColor(data.gradient?.startGradientColor) && isValidHexColor(data.gradient?.endGradientColor)) { + root.background = getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.dp_16).toInt(), + gradientColors = intArrayOf( + Color.parseColor(data.gradient?.startGradientColor), + Color.parseColor(data.gradient?.endGradientColor) + ) + ) + } + tvTag.text = data.tagData?.title?.text.spannedText( + context = context, + span = data.tagData?.title?.span + ) + tvTag.isVisible = data.tagData.isNotNull() + val startColor = data.tagData?.gradient?.startGradientColor + val endColor = data.tagData?.gradient?.endGradientColor + if (isValidHexColor(startColor) && isValidHexColor(endColor)) { + tvTag.background = getNaviDrawable( + gradientColors = intArrayOf( + Color.parseColor(startColor), + Color.parseColor(endColor) + ), + radii = CornerRadius( + leftBottom = dpToPx(8), + leftTop = dpToPx(0), + rightBottom = dpToPx(8), + rightTop = dpToPx(0), + ) + ) + } + data.imagePadding?.let { + image.setPadding( + dpToPxInInt(it.startDp.toInt()), + dpToPxInInt(it.topDp.toInt()), + dpToPxInInt(it.endDp.toInt()), + dpToPxInInt(it.bottomDp.toInt()) + ) + } + btnTitle.text = data.buttonData?.title?.text?.spannedText( + context = context, + span = data.buttonData.title.span + ) + if (isValidHexColor(data.buttonData?.bgColor)) { + actionBtn.background = getNaviDrawable( + cornerRadius = resources.getDimension(R.dimen.dp_20).toInt(), + backgroundColor = Color.parseColor(data.buttonData?.bgColor) + ) + } + btnIcon.showWhenDataIsAvailable(data.buttonData?.rightIconCode) + setOnClickListener { + widgetCallback.onClick( + NaviWidgetClickWithActionData( + actionData = data.actionData + ) + ) + } + shimmerAnimLottie.showWhenDataIsAvailable(data.lottieFileName) + setLottieDimensions(shimmerAnimLottie) + widgetCallback.widgetAnalytics( + genericAnalyticsData = data.metadata?.viewedData + ) + } + } + } + + private fun setLottieDimensions( + shimmerAnimLottie: LottieAnimationView + ) { + binding.rootCard.viewTreeObserver.addOnGlobalLayoutListener { + shimmerAnimLottie.layoutParams.height = binding.rootCard.height + shimmerAnimLottie.layoutParams.width = binding.rootCard.width + } + } +} + + + + + diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatReceivedMessageWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatReceivedMessageWidgetLayout.kt index 8718486477..225d1a0323 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatReceivedMessageWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatReceivedMessageWidgetLayout.kt @@ -1,9 +1,10 @@ /* * - * * Copyright © 2022 by Navi Technologies Private Limited + * * Copyright © 2022 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ + package com.navi.naviwidgets.widgets import android.content.Context @@ -17,11 +18,10 @@ import com.navi.naviwidgets.interfaces.NaviChatWidgetInfo import com.navi.naviwidgets.utils.convertTo24HourFormatTime import com.navi.naviwidgets.utils.setNaviChatMessageMargin -class NaviChatReceivedMessageWidgetLayout @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : ConstraintLayout(context, attrs, defStyleAttr) { +class NaviChatReceivedMessageWidgetLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { private lateinit var binding: LayoutNaviChatReceivedMessageBinding private lateinit var info: NaviChatWidgetInfo @@ -42,10 +42,10 @@ class NaviChatReceivedMessageWidgetLayout @JvmOverloads constructor( private fun setProperties() { binding.apply { tvReceivedMessage.showWhenDataIsAvailable(showText = info.message()) - tvTimestamp.showWhenDataIsAvailable(showText = info.timeStamp() - ?.let { timeStamp -> - convertTo24HourFormatTime(timeStamp) - }) + tvTimestamp.showWhenDataIsAvailable( + showText = + info.timeStamp()?.let { timeStamp -> convertTo24HourFormatTime(timeStamp) } + ) } } @@ -55,4 +55,4 @@ class NaviChatReceivedMessageWidgetLayout @JvmOverloads constructor( topMargin = binding.root.context.resources.getInteger(R.integer.integer_16) ) } -} \ No newline at end of file +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatTypingStatusLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatTypingStatusLayout.kt new file mode 100644 index 0000000000..020e5bdd45 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviChatTypingStatusLayout.kt @@ -0,0 +1,53 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.recyclerview.widget.RecyclerView +import com.navi.naviwidgets.R +import com.navi.naviwidgets.databinding.LayoutNaviChatTypingStatusBinding +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.response.NaviChatTypingStatusWidget +import com.navi.naviwidgets.utils.setNaviChatMessageMargin + +class NaviChatTypingStatusLayout +@JvmOverloads +constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LayoutNaviChatTypingStatusBinding + private lateinit var info: NaviChatTypingStatusWidget + private var widgetPosition: Int = Int.MAX_VALUE + + fun update( + info: NaviChatTypingStatusWidget, + binding: LayoutNaviChatTypingStatusBinding, + position: Int + ) { + this.binding = binding + this.info = info + this.widgetPosition = position + setProperties() + setMargin() + } + + private fun setProperties() { + binding.apply { + tvReceivedMessage.showWhenDataIsAvailable(showText = null, showHint = info.hint) + } + } + + private fun setMargin() { + (binding.root.layoutParams as? RecyclerView.LayoutParams)?.setNaviChatMessageMargin( + bottomMargin = binding.root.context.resources.getInteger(R.integer.integer_8), + topMargin = binding.root.context.resources.getInteger(R.integer.integer_16) + ) + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt index 8dc0fe5fd6..5ae51e3571 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/NaviWidgetJsonDeserializer.kt @@ -12,7 +12,6 @@ import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import com.navi.naviwidgets.models.* import com.navi.naviwidgets.models.ActionButtonWidget - import com.navi.naviwidgets.models.ElevatedIconWidgetData import com.navi.naviwidgets.models.response.* import com.navi.naviwidgets.models.response.dashboard.* @@ -129,6 +128,21 @@ class NaviWidgetJsonDeserializer : JsonDeserializer { TextWithUnderlineWidget.WIDGET_NAME -> TextWithUnderlineWidget::class.java CheckboxWithTitleWidgetModel.WIDGET_NAME -> CheckboxWithTitleWidgetModel::class.java + HomeStuProductWidget.WIDGET_NAME -> HomeStuProductWidget::class.java + HomeStuProductMiniWidget.WIDGET_NAME -> HomeStuProductMiniWidget::class.java + FreeInsuranceSuccessWidgetData.WIDGET_NAME -> FreeInsuranceSuccessWidgetData::class.java + ProductClickCardWidget.WIDGET_NAME -> ProductClickCardWidget::class.java + PostDisbursalSuccessWidget.WIDGET_NAME -> PostDisbursalSuccessWidget::class.java + LargeBannerWidget.WIDGET_NAME -> LargeBannerWidget::class.java + SingleImageWidget.WIDGET_NAME -> SingleImageWidget::class.java + BannerGridWidget.WIDGET_NAME -> BannerGridWidget::class.java + TrustedBuilderWidget.WIDGET_NAME -> TrustedBuilderWidget::class.java + ProductIntroWithButtonWidget.WIDGET_NAME -> ProductIntroWithButtonWidget::class.java + SliderWithDotIndicatorWidget.WIDGET_NAME -> SliderWithDotIndicatorWidget::class.java + ProductBenefitsGridWidget.WIDGET_NAME -> ProductBenefitsGridWidget::class.java + AppliedUserCountWidget.WIDGET_NAME -> AppliedUserCountWidget::class.java + UnderstandProcessVideoWidget.WIDGET_NAME -> UnderstandProcessVideoWidget::class.java + TwoInfoCardsWithTitleWidget.WIDGET_NAME -> TwoInfoCardsWithTitleWidget::class.java else -> null } return if (className != null) { diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsCardWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsCardWidgetLayout.kt new file mode 100644 index 0000000000..8b1932f4b7 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsCardWidgetLayout.kt @@ -0,0 +1,80 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.airbnb.lottie.LottieAnimationView +import com.airbnb.lottie.LottieCompositionFactory +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PolicyDetailsCardWidgetLayoutBinding +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.PolicyDetailsCardWidget +import com.navi.naviwidgets.utils.NaviWidgetIconUtils.updateIcon +import com.navi.naviwidgets.utils.setMaterialCardStyling +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class PolicyDetailsCardWidgetLayout +@JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + fun setProperties( + widgetData: PolicyDetailsCardWidget, + widgetCallback: WidgetCallback, + binding: PolicyDetailsCardWidgetLayoutBinding + ) { + setWidgetLayoutParams(widgetData.widgetLayoutParams(), binding.root) + widgetData.widgetBody?.let { widgetBody -> + binding.rootCard.setMaterialCardStyling(widgetBody.cardProperties) + binding.coverTitle.setTextFieldData(widgetBody.totalCoverTitle) + binding.coverValueTv.setTextFieldData(widgetBody.totalCoverValue) + binding.validUptoTitle.setTextFieldData(widgetBody.validUptoTitle) + binding.validUptoValueTv.setTextFieldData(widgetBody.validUptoValue) + binding.policyHolderTitle.setTextFieldData(widgetBody.policyHolderTitle) + binding.policyHolderValueTv.setTextFieldData(widgetBody.policyHolderValue) + updateIcon(widgetBody.topIconCode.orEmpty(), binding.logoIcon) + setLottieData(widgetBody.stampLottieCode, binding.stampAnimLottie) + setLottieData(widgetBody.shimmerLottieCode, binding.shimmerAnimLottie) + setLottieDimensions(binding, binding.shimmerAnimLottie) + } + } + + private fun setLottieDimensions( + binding: PolicyDetailsCardWidgetLayoutBinding, + shimmerAnimLottie: LottieAnimationView + ) { + binding.rootCard.viewTreeObserver.addOnGlobalLayoutListener { + shimmerAnimLottie.layoutParams.height = binding.rootCard.height + shimmerAnimLottie.layoutParams.width = binding.rootCard.width + } + } + + private fun setLottieData( + animationCode: String?, + lottieView: LottieAnimationView + ) { + context?.let { context -> + var rawFileResourceId: Int = resources.getIdentifier( + animationCode, + "raw", + context.packageName + ) + if (rawFileResourceId != -1) { + lottieView.removeAllAnimatorListeners() + LottieCompositionFactory.fromRawRes(context, rawFileResourceId).addListener { + lottieView.setComposition(it) + lottieView.playAnimation() + } + } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsWidgetLayout.kt new file mode 100644 index 0000000000..59eb7b08a8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PolicyDetailsWidgetLayout.kt @@ -0,0 +1,129 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.graphics.Color +import android.util.AttributeSet +import android.view.View +import android.widget.FrameLayout +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.navi.base.utils.isNull +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PolicyDetailsWidgetBinding +import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler +import com.navi.naviwidgets.extensions.setGradient +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.PolicyDetailsWidget +import com.navi.naviwidgets.models.response.PolicyDetailsWidgetBody +import com.navi.naviwidgets.utils.NaviWidgetIconUtils.updateIcon +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class PolicyDetailsWidgetLayout @JvmOverloads constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + private lateinit var binding: PolicyDetailsWidgetBinding + + fun setProperties( + infoData : PolicyDetailsWidget?, + widgetCallback: WidgetCallback?, + binding: PolicyDetailsWidgetBinding + ) { + this.binding = binding + + layoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + + setWidgetLayoutParams(infoData?.widgetLayoutParams, binding.root) + + val policyDetailsWidgetInfo: PolicyDetailsWidgetBody? = infoData?.widgetData() + + policyDetailsWidgetInfo?.let { + + //gradient + policyDetailsWidgetInfo.gradient?.let { + binding.rootView.setGradient(it) + } + + //title_info + policyDetailsWidgetInfo.titleInfo?.let { + binding.titleInfo.setTextFieldData(it) + } + + //title + policyDetailsWidgetInfo.title?.let { + binding.title.setTextFieldData(it) + } + + //subtitle + policyDetailsWidgetInfo.subtitle?.let { + binding.subtitle.setTextFieldData(it) + } + + //subtitle info + policyDetailsWidgetInfo.subtitleInfo?.let { + binding.subtitleInfo.setTextFieldData(it) + } + + //validity text + policyDetailsWidgetInfo.validityText?.let { + binding.validityInfo.setTextFieldData(it) + } + + //validity date + policyDetailsWidgetInfo.validityDate?.let { + binding.validityDate.setTextFieldData(it) + } + + //icon + updateIcon(policyDetailsWidgetInfo.iconCode.orEmpty(),binding.benefitsIcon) + + //policy expired tag + policyDetailsWidgetInfo.tag?.let { tag -> + binding.policyExpiredCard.visibility = View.VISIBLE + + tag.backgroundColor?.let { + binding.policyExpiredCard.setCardBackgroundColor(Color.parseColor(it)) + } + binding.policyExpiredCardTv.setTextFieldData(tag.title) + } + + //claims button + if(policyDetailsWidgetInfo.tag.isNull()) + { + policyDetailsWidgetInfo.button?.let { claimsBtn -> + binding.claimsCard.visibility= View.VISIBLE + claimsBtn.backgroundColor?.let { + binding.claimsCard.setCardBackgroundColor(Color.parseColor(it)) + } + binding.claimsCardTv.setTextFieldData(claimsBtn.title) + + binding.claimsCard.setOnClickListener{ + claimsBtn.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + } + } + } + + //description + policyDetailsWidgetInfo.description?.let { textFieldData -> + binding.toolbarDivider.isVisible = true + binding.descriptionTv.setTextFieldData(textFieldData) + binding.descriptionTv.addOnMultipleClicksHandler { + if (textFieldData.cta != null) { + widgetCallback?.onClick(textFieldData.cta) + } + } + } + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PostDisbursalSuccessWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PostDisbursalSuccessWidgetLayout.kt new file mode 100644 index 0000000000..941480b449 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/PostDisbursalSuccessWidgetLayout.kt @@ -0,0 +1,88 @@ +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.graphics.Color +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import androidx.recyclerview.widget.LinearLayoutManager +import com.navi.design.utils.spannedText +import com.navi.naviwidgets.R +import com.navi.naviwidgets.adapters.NaviAdapter +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.PostDisbursalSuccessWidgetLayoutBinding +import com.navi.naviwidgets.extensions.isValidHexColor +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.PostDisbursalSuccessWidget +import com.navi.naviwidgets.viewholder.ViewHolderFactoryImpl + +class PostDisbursalSuccessWidgetLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: PostDisbursalSuccessWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + private var widgetPosition: Int = Int.MAX_VALUE + private var widgetData: PostDisbursalSuccessWidget? = null + private var linearLayoutManager: LinearLayoutManager? = null + private val naviAdapter = NaviAdapter( + factory = ViewHolderFactoryImpl() + ) + + fun update( + widgetData: PostDisbursalSuccessWidget, + binding: PostDisbursalSuccessWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.widgetPosition = position + naviAdapter.widgetCallback = widgetCallback + setProperties() + } + + private fun setProperties() { + binding.apply { + widgetData?.postDisbursalSuccessWidgetData?.let { it -> + tvTitle.text = it.header?.title?.text.spannedText( + context = context, + span = it.header?.title?.span + ) + tvSubtitle.text = it.header?.description?.text.spannedText( + context = context, + span = it.header?.description?.span + ) + rightBg.showWhenDataIsAvailable(it.header?.iconUrl) + + it.items?.let { items -> + rvNaviWidgets.apply { + linearLayoutManager = LinearLayoutManager( + context, + LinearLayoutManager.VERTICAL, + false + ) + layoutManager = linearLayoutManager + naviAdapter.list = items + adapter = naviAdapter + } + } + rvNaviWidgetsCard.isVisible = it.items.isNullOrEmpty().not() + } + post { + val params = headerView.layoutParams + val extraHeight = if (rvNaviWidgetsCard.isVisible) resources.getDimensionPixelSize(R.dimen.dp_30) else 0 + params.height = + extraHeight + headerLayout.height - rvNaviWidgetsCard.height + widgetData?.postDisbursalSuccessWidgetData?.header?.bgColor?.let { bgColor -> + if (isValidHexColor(bgColor)) { + headerView.setBackgroundColor(Color.parseColor(bgColor)) + } + } + } + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductBenefitsGridWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductBenefitsGridWidgetLayout.kt new file mode 100644 index 0000000000..d76f8b577f --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductBenefitsGridWidgetLayout.kt @@ -0,0 +1,65 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.base.model.NaviBenefitsItemClick +import com.navi.naviwidgets.adapters.ProductBenefitsGridItemListAdapter +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutProductBenefitsGridWidgetBinding +import com.navi.naviwidgets.models.response.ProductBenefitsGridWidget +import com.navi.naviwidgets.models.response.ProductBenefitsGridWidgetData +import com.navi.naviwidgets.utils.setBackgroundColor + +class ProductBenefitsGridWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LayoutProductBenefitsGridWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: ProductBenefitsGridWidget + private lateinit var benefitsItemAdapter: ProductBenefitsGridItemListAdapter + private var position = Int.MAX_VALUE + + fun update( + widgetData: ProductBenefitsGridWidget, + binding: LayoutProductBenefitsGridWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + setProperties() + } + + private fun setProperties() { + binding.root.setBackgroundColor(widgetData.widgetLayoutParams?.backgroundColor) + binding.data = widgetData.productBenefitsGridWidgetData + widgetData.productBenefitsGridWidgetData?.let { productWidgetData -> + setUpAdapter(productWidgetData) + } + } + + private fun setUpAdapter(data: ProductBenefitsGridWidgetData) { + data.benefitsGridItems?.let { + benefitsItemAdapter = ProductBenefitsGridItemListAdapter(it, onItemClick = { position -> + widgetCallback.onClick( + NaviBenefitsItemClick( + ctaData = data.benefitsGridItems[position].cta, + position = position + ) + ) + }) + } + binding.rvBenefits.adapter = benefitsItemAdapter + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductClickCardWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductClickCardWidgetLayout.kt new file mode 100644 index 0000000000..4486ed7e87 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductClickCardWidgetLayout.kt @@ -0,0 +1,51 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ProductClickCardWidgetBinding +import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.ProductClickCardWidget +import com.navi.naviwidgets.utils.NaviWidgetIconUtils.updateIcon +import com.navi.naviwidgets.utils.setMaterialCardStyling +import com.navi.naviwidgets.utils.setWidgetLayoutParams + +class ProductClickCardWidgetLayout +@JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + fun setProperties( + widgetData: ProductClickCardWidget, + widgetCallback: WidgetCallback, + binding: ProductClickCardWidgetBinding + ) { + if(widgetData.widgetLayoutParams()?.gradient != null) { + setWidgetLayoutParams(widgetData.widgetLayoutParams(), binding.root) + } else { + setWidgetLayoutParams(widgetData.widgetLayoutParams()?.copy(gradient = widgetData.widgetBody?.backgroundGradient), binding.root) + } + widgetData.widgetBody?.let { widgetBody -> + binding.rootCard.setMaterialCardStyling(widgetBody.cardProperties) + updateIcon(widgetBody.rightIconCode.orEmpty(), binding.rightIconIv) + updateIcon(widgetBody.overlayIconCode.orEmpty(), binding.overlayIconIv) + updateIcon(widgetBody.imageUrl.orEmpty(), binding.iconIv) + binding.titleTv.setTextFieldData(widgetBody.title) + binding.subtitleTv.setTextFieldData(widgetBody.subtitle) + binding.rootCard.addOnMultipleClicksHandler { + widgetBody.cta?.let { ctaData -> widgetCallback.onClick(ctaData) } + } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductIntroWithButtonWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductIntroWithButtonWidgetLayout.kt new file mode 100644 index 0000000000..0bd86a721e --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/ProductIntroWithButtonWidgetLayout.kt @@ -0,0 +1,102 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import com.navi.base.model.NaviWidgetClickWithCtaData +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.ProductIntroWithButtonWidgetLayoutBinding +import com.navi.naviwidgets.extensions.showWhenDataIsAvailable +import com.navi.naviwidgets.models.response.ProductIntroWithButtonWidget +import java.util.* + +class ProductIntroWithButtonWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr), DefaultLifecycleObserver { + + private lateinit var binding: ProductIntroWithButtonWidgetLayoutBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: ProductIntroWithButtonWidget + private var position = Int.MAX_VALUE + private var timer: Timer? = null + private var lifecycle: Lifecycle? = null + + fun update( + widgetData: ProductIntroWithButtonWidget, + binding: ProductIntroWithButtonWidgetLayoutBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + lifecycle = widgetCallback.getLifeCycle() + lifecycle?.addObserver(this) + setProperties() + } + + private fun setProperties() { + binding.data = widgetData.productIntroWithButtonWidgetData + widgetData.productIntroWithButtonWidgetData?.let { productWidgetData -> + binding.tvAction.apply { + setOnClickListener { + widgetCallback.onClick(NaviWidgetClickWithCtaData( + ctaData = productWidgetData.cta + )) + } + } + } + } + + override fun onResume(owner: LifecycleOwner) { + super.onResume(owner) + setProductSubtitle() + } + + private fun setProductSubtitle() { + timer = Timer() + binding.productSubtitleTextSwitcher.apply { + removeAllViews() + setFactory { TextView(context) } + showWhenDataIsAvailable( + widgetData.productIntroWithButtonWidgetData?.subTitleList, timer, + period = widgetData.productIntroWithButtonWidgetData?.titleSlideIntervalTime + ?: DEFAULT_SLIDE_PERIOD_TIME + ) { productTitle -> + Handler(Looper.getMainLooper()).post { + binding.productSubtitleTextSwitcher.setText(productTitle) + } + } + } + } + + override fun onPause(owner: LifecycleOwner) { + super.onPause(owner) + timer?.cancel() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + timer?.cancel() + this.lifecycle?.removeObserver(this) + } + + companion object { + private const val DEFAULT_SLIDE_PERIOD_TIME = 2000L + } + +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SingleImageWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SingleImageWidgetLayout.kt index fc90518fe4..84aa1408c3 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SingleImageWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SingleImageWidgetLayout.kt @@ -12,6 +12,9 @@ import android.graphics.drawable.Drawable import android.util.AttributeSet import android.widget.FrameLayout import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.airbnb.lottie.LottieAnimationView +import com.airbnb.lottie.LottieCompositionFactory import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -26,8 +29,8 @@ import com.navi.naviwidgets.extensions.getScreenWidth import com.navi.naviwidgets.interfaces.SingleImageWidgetInfo import com.navi.naviwidgets.models.response.SingleImageWidgetBody import com.navi.naviwidgets.utils.setWidgetLayoutParams -import kotlin.math.roundToInt import timber.log.Timber +import kotlin.math.roundToInt class SingleImageWidgetLayout @JvmOverloads @@ -72,9 +75,39 @@ constructor( ((getScreenWidth() - (horizontalMargins + horizontalPadding)).toDouble() / (it.aspectRatio ?: defaultAspectRatio).toDouble()) .roundToInt() + verticalPadding - loadImageFromUrl(binding, it.imageUrl) - binding.imageView.setOnClickListener { view -> - it.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + if (it.type == TYPE_LOTTIE) { + setLottieData(animationCode = it.imageUrl, lottieView = binding.lottie) + binding.placeholderImage.alpha = ALPHA_INVISIBLE + binding.imageView.alpha = ALPHA_INVISIBLE + binding.lottie.isVisible = true + binding.lottie.setOnClickListener { view -> + it.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + } + } else { + loadImageFromUrl(binding, it.imageUrl) + binding.imageView.setOnClickListener { view -> + it.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + } + } + } + } + + private fun setLottieData( + animationCode: String?, + lottieView: LottieAnimationView + ) { + context?.let { context -> + var rawFileResourceId: Int = resources.getIdentifier( + animationCode, + "raw", + context.packageName + ) + if (rawFileResourceId != -1) { + lottieView.removeAllAnimatorListeners() + LottieCompositionFactory.fromRawRes(context, rawFileResourceId).addListener { + lottieView.setComposition(it) + lottieView.playAnimation() + } } } } @@ -152,4 +185,8 @@ constructor( ) .into(viewBinding.imageView) } + + companion object { + const val TYPE_LOTTIE = "TYPE_LOTTIE" + } } diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SliderWithDotIndicatorsWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SliderWithDotIndicatorsWidgetLayout.kt new file mode 100644 index 0000000000..3ab0aa5fb0 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/SliderWithDotIndicatorsWidgetLayout.kt @@ -0,0 +1,116 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.PagerSnapHelper +import com.navi.naviwidgets.R +import com.navi.naviwidgets.adapters.CirclePagerIndicatorDecoration +import com.navi.naviwidgets.adapters.SliderWithDotsIndicatorItemAdapter +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutSliderWithDotsIndicatorWidgetBinding +import com.navi.naviwidgets.models.response.SliderWithDotIndicatorWidget +import com.navi.naviwidgets.models.response.SliderWithDotIndicatorWidgetData +import java.util.* + +class SliderWithDotIndicatorsWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr), DefaultLifecycleObserver { + + private lateinit var binding: LayoutSliderWithDotsIndicatorWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: SliderWithDotIndicatorWidget + private var position = Int.MAX_VALUE + private lateinit var sliderAdapter: SliderWithDotsIndicatorItemAdapter + private var lifecycle: Lifecycle? = null + private var timer: Timer? = null + + fun update( + widgetData: SliderWithDotIndicatorWidget, + binding: LayoutSliderWithDotsIndicatorWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + lifecycle = widgetCallback.getLifeCycle() + lifecycle?.addObserver(this) + setProperties() + } + + private fun setProperties() { + widgetData.sliderWithDotIndicatorWidgetData?.let { sliderWidgetData -> + setUpRecyclerview(sliderWidgetData) + scrollItemsAutomatically() + } + } + + override fun onResume(owner: LifecycleOwner) { + super.onResume(owner) + if (this@SliderWithDotIndicatorsWidgetLayout::sliderAdapter.isInitialized) { + scrollItemsAutomatically() + } + } + + private fun setUpRecyclerview(sliderWidgetData: SliderWithDotIndicatorWidgetData) { + sliderAdapter = SliderWithDotsIndicatorItemAdapter(sliderWidgetData.items) + binding.rvItemList.apply { + adapter = sliderAdapter + addItemDecoration( + CirclePagerIndicatorDecoration( + colorActive = ContextCompat.getColor(context, R.color.outrageous_orange), + colorInactive = ContextCompat.getColor(context, R.color.defaultColor) + ) + ) + PagerSnapHelper().attachToRecyclerView(this) + } + } + + private fun scrollItemsAutomatically() { + var itemPosition = 0 + timer = Timer() + val timerTask: TimerTask = object : TimerTask() { + override fun run() { + if (itemPosition >= sliderAdapter.itemCount) itemPosition = 0 + binding.rvItemList.smoothScrollToPosition(itemPosition) + itemPosition++ + } + } + timer?.schedule( + timerTask, + widgetData.sliderWithDotIndicatorWidgetData?.bannerInitialDelay + ?: DEFAULT_SLIDE_INITIAL_DELAY, + widgetData.sliderWithDotIndicatorWidgetData?.bannerSlideIntervalTime + ?: DEFAULT_SLIDE_PERIOD_TIME + ) + } + + override fun onPause(owner: LifecycleOwner) { + super.onPause(owner) + timer?.cancel() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + timer?.cancel() + this.lifecycle?.removeObserver(this) + } + + companion object { + private const val DEFAULT_SLIDE_INITIAL_DELAY = 0L + private const val DEFAULT_SLIDE_PERIOD_TIME = 2000L + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextInputUtil.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextInputUtil.kt index 19ed76b8da..9d331bb5e0 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextInputUtil.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TextInputUtil.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.naviwidgets.widgets import android.text.InputType @@ -10,16 +17,18 @@ object TextInputUtil { list?.forEach { when (it) { INPUT_TYPE_TEXT -> result = result or EditorInfo.TYPE_CLASS_TEXT - INPUT_TYPE_TEXT_PERSON_NAME -> result = - result or EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME + INPUT_TYPE_TEXT_PERSON_NAME -> + result = result or EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME INPUT_TYPE_TEXT_CAP_WORDS -> result = result or EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS INPUT_TYPE_PHONE -> result = result or EditorInfo.TYPE_CLASS_PHONE INPUT_TYPE_NUMBER -> result = result or EditorInfo.TYPE_CLASS_NUMBER - INPUT_TYPE_NUMBER_DECIMAL -> result = result or InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_CLASS_NUMBER - INPUT_TYPE_TEXT_CAP_CHARACTERS -> result = - result or EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS - INPUT_TYPE_TEXT_EMAIL_ADDRESS -> result = - result or EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + INPUT_TYPE_NUMBER_DECIMAL -> + result = + result or InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_CLASS_NUMBER + INPUT_TYPE_TEXT_CAP_CHARACTERS -> + result = result or EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS + INPUT_TYPE_TEXT_EMAIL_ADDRESS -> + result = result or EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS } } return if (result == EditorInfo.TYPE_NULL) { @@ -37,4 +46,5 @@ object TextInputUtil { const val INPUT_TYPE_NUMBER_DECIMAL = "numberDecimal" const val INPUT_TYPE_TEXT_CAP_CHARACTERS = "textCapCharacters" const val INPUT_TYPE_TEXT_EMAIL_ADDRESS = "emailAddress" -} \ No newline at end of file + const val REGEX_ALPHA_NUMERIC = "^[a-zA-Z0-9_]*$" +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TitleDescIconCtaWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TitleDescIconCtaWidgetLayout.kt new file mode 100644 index 0000000000..e9722d1f80 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TitleDescIconCtaWidgetLayout.kt @@ -0,0 +1,101 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.content.res.ColorStateList +import android.util.AttributeSet +import android.view.View +import android.widget.FrameLayout +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.design.utils.parseColorSafe +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.TitleDescIconCtaWidgetLayoutBinding +import com.navi.naviwidgets.extensions.setImageFieldData +import com.navi.naviwidgets.extensions.isValidHexColor +import com.navi.naviwidgets.extensions.setTextFieldData +import com.navi.naviwidgets.models.response.TitleDescIconCtaWidget +import com.navi.naviwidgets.models.response.TitleDescIconCtaWidgetBody +import com.navi.naviwidgets.utils.* + +class TitleDescIconCtaWidgetLayout +@JvmOverloads +constructor( + private val parentContext: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(parentContext, attrs, defStyleAttr) { + + private lateinit var binding: TitleDescIconCtaWidgetLayoutBinding + private var DEFAULT_ITEM_TEXT = "" + + fun setProperties( + tdicInfoWidgetData: TitleDescIconCtaWidget?, + widgetCallback: WidgetCallback?, + binding: TitleDescIconCtaWidgetLayoutBinding, + ) { + this.binding = binding + + layoutParams = + FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + setWidgetLayoutParams(tdicInfoWidgetData?.widgetLayoutParams, binding.root) + val tdicWidgetInfo: TitleDescIconCtaWidgetBody? = tdicInfoWidgetData?.widgetData() + + tdicWidgetInfo?.let { tdicWidgetData -> + // info icon + tdicWidgetData.leftIcon?.let { + binding.infoIcon.setImageFieldData(it) + } + + // chevron icon + tdicWidgetData.chevronIconCode?.let { iconCode -> + val imageResId = NaviWidgetIconUtils.getImageFromIconCode(iconCode) + if (imageResId != -1) { + binding.chevronIcon.setImageResource(imageResId) + } + } + + // title + tdicWidgetData.title?.let { binding.title.setTextFieldData(it) } + + // subtitle + tdicWidgetInfo.subTitle?.let { + binding.toolbarDivider.visibility = View.VISIBLE + binding.subtitle.visibility = View.VISIBLE + binding.subtitle.setTextFieldData(it) + } + + if (tdicWidgetInfo.cta == null) { + binding.chevronIcon.visibility = View.GONE + } + + // rightText + tdicWidgetInfo.rightText?.let { + binding.rightText.visibility = View.VISIBLE + binding.rightText.setTextFieldData(it) + } + + // pillItemData + tdicWidgetInfo.pillItemData?.let { + binding.card1.visibility = View.VISIBLE + if(isValidHexColor(it.backgroundColor)) { + binding.card1.backgroundTintList = ColorStateList.valueOf(it.backgroundColor.parseColorSafe()) + } + binding.pillItemData.setTextFieldData(it.title) + } + + // set onClick + binding.root.setOnClickListener { + tdicWidgetInfo.cta?.let { ctaData -> widgetCallback?.onClick(ctaData) } + } + } + } +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TrustedBuildersWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TrustedBuildersWidgetLayout.kt new file mode 100644 index 0000000000..b277fa3809 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TrustedBuildersWidgetLayout.kt @@ -0,0 +1,104 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.LinearLayoutManager +import com.navi.naviwidgets.adapters.BuilderIconsListAdapter +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutTrustedBuildersWidgetBinding +import com.navi.naviwidgets.models.response.TrustedBuilderWidget +import com.navi.naviwidgets.models.response.TrustedBuilderWidgetData +import java.util.* + +class TrustedBuildersWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr), DefaultLifecycleObserver { + + private lateinit var binding: LayoutTrustedBuildersWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: TrustedBuilderWidget + private lateinit var builderIconsListAdapter: BuilderIconsListAdapter + private var position = Int.MAX_VALUE + private var lifecycle: Lifecycle? = null + private var timer: Timer? = null + + fun update( + widgetData: TrustedBuilderWidget, + binding: LayoutTrustedBuildersWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + lifecycle = widgetCallback.getLifeCycle() + lifecycle?.addObserver(this) + setProperties() + } + + private fun setProperties() { + binding.data = widgetData.trustedBuilderWidgetData + widgetData.trustedBuilderWidgetData?.let { builderWidgetData -> + setUpRecyclerview(builderWidgetData) + } + } + + override fun onResume(owner: LifecycleOwner) { + super.onResume(owner) + scrollItemsAutomatically() + } + + private fun setUpRecyclerview(builderWidgetData: TrustedBuilderWidgetData) { + builderWidgetData.builderInfo?.builderIcons?.let { iconsUrl -> + builderIconsListAdapter = BuilderIconsListAdapter() + builderIconsListAdapter.updateIconsUrlList(iconsUrl) + } + binding.rvIconsList.adapter = builderIconsListAdapter + } + + private fun scrollItemsAutomatically() { + timer = Timer() + val timerTask: TimerTask = object : TimerTask() { + override fun run() { + val lastItemPosition: Int = + (binding.rvIconsList.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition() + if (lastItemPosition >= builderIconsListAdapter.itemCount - 1) { + timer?.cancel() + } else { + binding.rvIconsList.smoothScrollBy(SCROLL_DX, 0) + } + } + } + timer?.schedule(timerTask, DELAY_BETWEEN_SCROLL_MS, TIMER_PERIOD) + } + + override fun onPause(owner: LifecycleOwner) { + super.onPause(owner) + timer?.cancel() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + timer?.cancel() + this.lifecycle?.removeObserver(this) + } + + companion object { + private const val DELAY_BETWEEN_SCROLL_MS = 10L + private const val SCROLL_DX = 10 + private const val TIMER_PERIOD = 50L + } + +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TwoInfoCardsWithTitleWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TwoInfoCardsWithTitleWidgetLayout.kt new file mode 100644 index 0000000000..f458a1ead8 --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/TwoInfoCardsWithTitleWidgetLayout.kt @@ -0,0 +1,55 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutTwoIfnoCardsWithTitleWidgetBinding +import com.navi.naviwidgets.models.response.TwoInfoCardsWithTitleWidget +import com.navi.naviwidgets.utils.setBackgroundColor +import com.navi.naviwidgets.utils.setPadding + +class TwoInfoCardsWithTitleWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LayoutTwoIfnoCardsWithTitleWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: TwoInfoCardsWithTitleWidget + private var position = Int.MAX_VALUE + + fun update( + widgetData: TwoInfoCardsWithTitleWidget, + binding: LayoutTwoIfnoCardsWithTitleWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + setProperties() + } + + private fun setProperties() { + binding.data = widgetData.twoInfoCardsWithTitleWidgetData + binding.root.apply { + setPadding(widgetData.widgetLayoutParams) + setBackgroundColor(widgetData.widgetLayoutParams?.backgroundColor) + } + widgetData.twoInfoCardsWithTitleWidgetData?.let { twoInfoCardsWidgetData -> + binding.apply { + firstItem.data = twoInfoCardsWidgetData.loanDisbursedItem + secondItem.data = twoInfoCardsWidgetData.loanApplicationsItem + } + } + } + +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UnderstandProcessVideoWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UnderstandProcessVideoWidgetLayout.kt new file mode 100644 index 0000000000..fcc37a225c --- /dev/null +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UnderstandProcessVideoWidgetLayout.kt @@ -0,0 +1,53 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.naviwidgets.widgets + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import com.navi.base.model.NaviWidgetClickWithCtaData +import com.navi.naviwidgets.callbacks.WidgetCallback +import com.navi.naviwidgets.databinding.LayoutUnderstandProcessVideoWidgetBinding +import com.navi.naviwidgets.models.response.UnderstandProcessVideoWidget + +class UnderstandProcessVideoWidgetLayout @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private lateinit var binding: LayoutUnderstandProcessVideoWidgetBinding + private lateinit var widgetCallback: WidgetCallback + private lateinit var widgetData: UnderstandProcessVideoWidget + private var position = Int.MAX_VALUE + + fun update( + widgetData: UnderstandProcessVideoWidget, + binding: LayoutUnderstandProcessVideoWidgetBinding, + widgetCallback: WidgetCallback, + position: Int + ) { + this.widgetData = widgetData + this.binding = binding + this.widgetCallback = widgetCallback + this.position = position + setProperties() + } + + private fun setProperties() { + widgetData.understandProcessWidgetData?.let { underProcessWidgetData -> + binding.data = underProcessWidgetData + binding.flVideoThumbnail.apply { + data = underProcessWidgetData + layoutVideoThumbnail.setOnClickListener { + widgetCallback.onClick( + NaviWidgetClickWithCtaData(ctaData = underProcessWidgetData.ctaData) + ) + } + } + } + } +} \ No newline at end of file diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UserInfoWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UserInfoWidgetLayout.kt index c378de6ef1..cc809118ae 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UserInfoWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/UserInfoWidgetLayout.kt @@ -1,3 +1,10 @@ +/* + * + * * Copyright © 2022 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + package com.navi.naviwidgets.widgets import android.content.Context @@ -10,14 +17,12 @@ import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler import com.navi.naviwidgets.extensions.setTextFieldData import com.navi.naviwidgets.interfaces.UserInfoWidgetInfo import com.navi.naviwidgets.models.response.UserInfoWidgetBody -import com.navi.naviwidgets.utils.setMaterialCardProperties import com.navi.naviwidgets.utils.setWidgetLayoutParams - -class UserInfoWidgetLayout @JvmOverloads constructor( - private val parentContext: Context, - attributes: AttributeSet? = null -) : ConstraintLayout(parentContext, attributes) { +class UserInfoWidgetLayout +@JvmOverloads +constructor(private val parentContext: Context, attributes: AttributeSet? = null) : + ConstraintLayout(parentContext, attributes) { private var binding: UserInfoWidgetBinding? = null fun setProperties( @@ -26,29 +31,24 @@ class UserInfoWidgetLayout @JvmOverloads constructor( binding: UserInfoWidgetBinding ) { this.binding = binding - layoutParams = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT - ) - setWidgetLayoutParams( - cardWithMemberDetailsData.widgetLayoutParams(), - binding.rootCl - ) + layoutParams = + FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + setWidgetLayoutParams(cardWithMemberDetailsData.widgetLayoutParams(), binding.rootCl) val cardWithMemberDetailsDataInfo: UserInfoWidgetBody? = cardWithMemberDetailsData.widgetData() cardWithMemberDetailsDataInfo?.let { widgetData -> - binding.title.setTextFieldData(widgetData.title) binding.description.setTextFieldData(widgetData.description) binding.rightText.setTextFieldData(widgetData.rightText) widgetData.rightText?.cta?.let { cta -> - binding.rightText.addOnMultipleClicksHandler { - widgetCallback.onClick(cta) - } + binding.rightText.addOnMultipleClicksHandler { widgetCallback.onClick(cta) } } } } -} \ No newline at end of file +} diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/dashboard/DashboardInsuranceDetailsWidgetLayout.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/dashboard/DashboardInsuranceDetailsWidgetLayout.kt index 431108b57a..da4e3785e3 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/dashboard/DashboardInsuranceDetailsWidgetLayout.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/dashboard/DashboardInsuranceDetailsWidgetLayout.kt @@ -26,8 +26,9 @@ import com.navi.naviwidgets.actions.NavigateClickAction import com.navi.naviwidgets.actions.ShowBottomSheetClicked import com.navi.naviwidgets.callbacks.WidgetCallback import com.navi.naviwidgets.databinding.LayoutDashboardInsuranceDetailsBinding +import com.navi.naviwidgets.extensions.addOnMultipleClicksHandler import com.navi.naviwidgets.extensions.isValidHexColor -import com.navi.naviwidgets.extensions.setSpannableString +import com.navi.naviwidgets.extensions.setTextFieldData import com.navi.naviwidgets.extensions.showWhenDataIsAvailable import com.navi.naviwidgets.interfaces.DashboardInsuranceDetailsWidgetInfo import com.navi.naviwidgets.utils.NaviWidgetIconUtils @@ -76,15 +77,26 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 tvLeftTopText.showWhenDataIsAvailable(showText = info.leftTopText()) tvLeftTopSubText.showWhenDataIsAvailable(showText = info.leftTopSubText()) + tvLeftTopSubText.textSize = info.leftTopSubTextSize() ?: 16f tvRightTopText.showWhenDataIsAvailable(showText = info.rightTopText()) tvRightTopSubText.showWhenDataIsAvailable(showText = info.rightTopSubText()) + tvRightTopSubText.textSize = info.rightTopSubTextSize() ?: 16f tvLeftBottomText.showWhenDataIsAvailable(showText = info.leftBottomText()) tvLeftBottomSubText.showWhenDataIsAvailable(showText = info.leftBottomSubText()) + tvLeftBottomSubText.textSize = info.leftBottomSubTextSize() ?: 14f tvRightBottomText.showWhenDataIsAvailable(showText = info.rightBottomText()) tvRightBottomSubText.showWhenDataIsAvailable(showText = info.rightBottomSubText()) + tvRightBottomSubText.textSize = info.rightBottomSubTextSize() ?: 14f + + tag.isVisible = if (info.getTag()?.title?.text != null) { + tag.setTextFieldData(info.getTag()?.title) + true + } else { + false + } NaviWidgetIconUtils.updateIcon( imageDetail = @@ -101,6 +113,21 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 } } + info.leftBottomRightIcon()?.let { imageFieldData -> + val iconRes = NaviWidgetIconUtils.getImageFromIconCode(imageFieldData.iconCode) + if (iconRes != -1) { + ivLeftBottomSubText.setImageResource(iconRes) + } + if (imageFieldData.actionData != null) { + for (view in arrayOf(tvLeftBottomSubText, ivLeftBottomSubText)) { + view.addOnMultipleClicksHandler { + widgetCallback.onClick(imageFieldData.actionData) + widgetCallback.widgetAnalytics(imageFieldData.actionData.metaData?.clickedData) + } + } + } + } + tvPrimaryAction.showWhenDataIsAvailable( showText = info.actionData()?.primaryAction?.title ) @@ -132,13 +159,13 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 if (info.offerData() == null) { offerLayout.isVisible = false } else { - binding.leftIcon.isVisible = + binding.offerLeftIcon.isVisible = info .offerData() ?.leftIcon ?.takeIf { it.isNotEmpty() } ?.let { - binding.leftIcon.setImageResource( + binding.offerLeftIcon.setImageResource( NaviWidgetIconUtils.getIconResourceId(it) ) true @@ -263,6 +290,47 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) } } + if (info.footerData() != null) { + footerContainer.isVisible = true + val leftIconCode = info.footerData()?.leftIcon + if (leftIconCode != null && NaviWidgetIconUtils.getIconResourceId(leftIconCode) != -1) { + footerLeftIcon.isVisible = true + footerLeftIcon.setImageResource(NaviWidgetIconUtils.getIconResourceId(leftIconCode)) + } else { + footerLeftIcon.isVisible = false + } + footerTitle.setSpannableString(info.footerData()?.title) + footerSubTitle.setSpannableString(info.footerData()?.subTitle) + val startColor = info.footerData()?.gradient?.startGradientColor + val endColor = info.footerData()?.gradient?.endGradientColor + if (isValidHexColor(startColor) && isValidHexColor(endColor)) { + footerContainer.background = + getNaviDrawable( + radii = + CornerRadius( + rightBottom = resources.getDimension(R.dimen.dp_16), + leftBottom = resources.getDimension(R.dimen.dp_16), + rightTop = resources.getDimension(R.dimen.dp_0), + leftTop = resources.getDimension(R.dimen.dp_0) + ), + gradientColors = + intArrayOf( + Color.parseColor(startColor), + Color.parseColor(endColor) + ) + ) + } + info.footerData()?.actionData?.let { actionData -> + footerContainer.addOnMultipleClicksHandler { + widgetCallback.onClick(actionData) + widgetCallback.widgetAnalytics( + genericAnalyticsData = info.footerData()?.actionData?.metaData?.clickedData + ) + } + } + } else { + footerContainer.isVisible = false + } } } } diff --git a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/textdisplay/Padding.kt b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/textdisplay/Padding.kt index 526149622b..fed5207d33 100644 --- a/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/textdisplay/Padding.kt +++ b/navi-widgets/src/main/java/com/navi/naviwidgets/widgets/textdisplay/Padding.kt @@ -11,7 +11,7 @@ import com.google.gson.annotations.SerializedName import java.io.Serializable class Padding( - @SerializedName("startDP") var startDp: Float = 0.0f, + @SerializedName("startDP", alternate = ["startDp"]) var startDp: Float = 0.0f, @SerializedName("endDp") var endDp: Float = 0.0f, @SerializedName("topDp") var topDp: Float = 0.0f, @SerializedName("bottomDp") var bottomDp: Float = 0.0f diff --git a/navi-widgets/src/main/res/drawable/alert_policy_icon.xml b/navi-widgets/src/main/res/drawable/alert_policy_icon.xml new file mode 100644 index 0000000000..e77f032d73 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/alert_policy_icon.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/navi-widgets/src/main/res/drawable/badge_plus_upgrade.xml b/navi-widgets/src/main/res/drawable/badge_plus_upgrade.xml new file mode 100644 index 0000000000..c031dd21c1 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/badge_plus_upgrade.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/bg_circular.xml b/navi-widgets/src/main/res/drawable/bg_circular.xml new file mode 100644 index 0000000000..916a766580 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/bg_circular.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/navi-widgets/src/main/res/drawable/bg_trusted_builder_widget.xml b/navi-widgets/src/main/res/drawable/bg_trusted_builder_widget.xml new file mode 100644 index 0000000000..1f1bdf9992 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/bg_trusted_builder_widget.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/bg_video_duration.xml b/navi-widgets/src/main/res/drawable/bg_video_duration.xml new file mode 100644 index 0000000000..4aa855571b --- /dev/null +++ b/navi-widgets/src/main/res/drawable/bg_video_duration.xml @@ -0,0 +1,10 @@ + + + diff --git a/navi-widgets/src/main/res/drawable/bg_video_thumbnail.xml b/navi-widgets/src/main/res/drawable/bg_video_thumbnail.xml new file mode 100644 index 0000000000..80bef609a2 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/bg_video_thumbnail.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/navi-widgets/src/main/res/drawable/button_footer_background.xml b/navi-widgets/src/main/res/drawable/button_footer_background.xml new file mode 100644 index 0000000000..27386b511a --- /dev/null +++ b/navi-widgets/src/main/res/drawable/button_footer_background.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/circular_border_grey_16.xml b/navi-widgets/src/main/res/drawable/circular_border_grey_16.xml new file mode 100644 index 0000000000..ce0796ceeb --- /dev/null +++ b/navi-widgets/src/main/res/drawable/circular_border_grey_16.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/dash_line.xml b/navi-widgets/src/main/res/drawable/dash_line.xml new file mode 100644 index 0000000000..b174efd987 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/dash_line.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/dash_line_horizontal_grey.xml b/navi-widgets/src/main/res/drawable/dash_line_horizontal_grey.xml new file mode 100644 index 0000000000..47cc8236f3 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/dash_line_horizontal_grey.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/dashed_line_2.xml b/navi-widgets/src/main/res/drawable/dashed_line_2.xml new file mode 100644 index 0000000000..e9c63c6cbd --- /dev/null +++ b/navi-widgets/src/main/res/drawable/dashed_line_2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/exipry_alert_icon.xml b/navi-widgets/src/main/res/drawable/exipry_alert_icon.xml new file mode 100644 index 0000000000..6d815eeda4 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/exipry_alert_icon.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/expired_policy_icon.xml b/navi-widgets/src/main/res/drawable/expired_policy_icon.xml new file mode 100644 index 0000000000..004e888bf8 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/expired_policy_icon.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/gift_icon_with_congrats_svg.xml b/navi-widgets/src/main/res/drawable/gift_icon_with_congrats_svg.xml new file mode 100644 index 0000000000..a22511a8e6 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/gift_icon_with_congrats_svg.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/hand_upgrade.xml b/navi-widgets/src/main/res/drawable/hand_upgrade.xml new file mode 100644 index 0000000000..f019a01c92 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/hand_upgrade.xml @@ -0,0 +1,13 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/home_loan_intro.xml b/navi-widgets/src/main/res/drawable/home_loan_intro.xml new file mode 100644 index 0000000000..52eb6a7fbc --- /dev/null +++ b/navi-widgets/src/main/res/drawable/home_loan_intro.xml @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_clock_ticking.xml b/navi-widgets/src/main/res/drawable/ic_clock_ticking.xml new file mode 100644 index 0000000000..2ae5bd2b51 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_clock_ticking.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_confetti_left_pop.xml b/navi-widgets/src/main/res/drawable/ic_confetti_left_pop.xml new file mode 100644 index 0000000000..c3e31f26fe --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_confetti_left_pop.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_confetti_right_pop.xml b/navi-widgets/src/main/res/drawable/ic_confetti_right_pop.xml new file mode 100644 index 0000000000..9bd5feab05 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_confetti_right_pop.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_description_bg.xml b/navi-widgets/src/main/res/drawable/ic_description_bg.xml new file mode 100644 index 0000000000..83b575bbcb --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_description_bg.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_error_outlined.xml b/navi-widgets/src/main/res/drawable/ic_error_outlined.xml new file mode 100644 index 0000000000..b526ce7d76 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_error_outlined.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_expired.xml b/navi-widgets/src/main/res/drawable/ic_expired.xml new file mode 100644 index 0000000000..2bd242c8a4 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_expired.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_gift_box.xml b/navi-widgets/src/main/res/drawable/ic_gift_box.xml new file mode 100644 index 0000000000..0ad1f6eb9b --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_gift_box.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_hands_with_heart.xml b/navi-widgets/src/main/res/drawable/ic_hands_with_heart.xml new file mode 100644 index 0000000000..120c57056d --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_hands_with_heart.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_lock_red.xml b/navi-widgets/src/main/res/drawable/ic_lock_red.xml new file mode 100644 index 0000000000..7276a5650d --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_lock_red.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_magnifier_lens.xml b/navi-widgets/src/main/res/drawable/ic_magnifier_lens.xml new file mode 100644 index 0000000000..1a6d3db8b8 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_magnifier_lens.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_navi_logo_in_white_card.xml b/navi-widgets/src/main/res/drawable/ic_navi_logo_in_white_card.xml new file mode 100644 index 0000000000..730a2b3be7 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_navi_logo_in_white_card.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_new_glowing_bulb.xml b/navi-widgets/src/main/res/drawable/ic_new_glowing_bulb.xml new file mode 100644 index 0000000000..549856f730 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_new_glowing_bulb.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_play_button.xml b/navi-widgets/src/main/res/drawable/ic_play_button.xml new file mode 100644 index 0000000000..31027435e2 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_play_button.xml @@ -0,0 +1,13 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_play_video.xml b/navi-widgets/src/main/res/drawable/ic_play_video.xml new file mode 100644 index 0000000000..b65b517706 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_play_video.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_property_image_placeholder.xml b/navi-widgets/src/main/res/drawable/ic_property_image_placeholder.xml new file mode 100644 index 0000000000..5705f3f81f --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_property_image_placeholder.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_rbi_registered.xml b/navi-widgets/src/main/res/drawable/ic_rbi_registered.xml new file mode 100644 index 0000000000..7fead125f3 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_rbi_registered.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_sad_pot.xml b/navi-widgets/src/main/res/drawable/ic_sad_pot.xml new file mode 100644 index 0000000000..4b7816bac8 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_sad_pot.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_translucent_video_play_button.xml b/navi-widgets/src/main/res/drawable/ic_translucent_video_play_button.xml new file mode 100644 index 0000000000..77a7277431 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_translucent_video_play_button.xml @@ -0,0 +1,14 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/ic_widget_alert_black.xml b/navi-widgets/src/main/res/drawable/ic_widget_alert_black.xml new file mode 100644 index 0000000000..97c2c3a421 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ic_widget_alert_black.xml @@ -0,0 +1,14 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/icon_hand_wave.xml b/navi-widgets/src/main/res/drawable/icon_hand_wave.xml new file mode 100644 index 0000000000..120c57056d --- /dev/null +++ b/navi-widgets/src/main/res/drawable/icon_hand_wave.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/image_loan_applications.xml b/navi-widgets/src/main/res/drawable/image_loan_applications.xml new file mode 100644 index 0000000000..5267945b05 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/image_loan_applications.xml @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/img_loan_amount_disbursed.xml b/navi-widgets/src/main/res/drawable/img_loan_amount_disbursed.xml new file mode 100644 index 0000000000..7a7c80a098 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/img_loan_amount_disbursed.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/insurance_hospital_small.xml b/navi-widgets/src/main/res/drawable/insurance_hospital_small.xml new file mode 100644 index 0000000000..f21c5b0004 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/insurance_hospital_small.xml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/drawable/light_green_white_gradient_background.xml b/navi-widgets/src/main/res/drawable/light_green_white_gradient_background.xml new file mode 100644 index 0000000000..cc2fa9c294 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/light_green_white_gradient_background.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/ready_policy_icon.xml b/navi-widgets/src/main/res/drawable/ready_policy_icon.xml new file mode 100644 index 0000000000..96626018de --- /dev/null +++ b/navi-widgets/src/main/res/drawable/ready_policy_icon.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/navi-widgets/src/main/res/drawable/right_arrow_in_blue_circle.xml b/navi-widgets/src/main/res/drawable/right_arrow_in_blue_circle.xml new file mode 100644 index 0000000000..6772f16c87 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/right_arrow_in_blue_circle.xml @@ -0,0 +1,12 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/right_arrow_in_orange_circle.xml b/navi-widgets/src/main/res/drawable/right_arrow_in_orange_circle.xml new file mode 100644 index 0000000000..8754aee2a1 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/right_arrow_in_orange_circle.xml @@ -0,0 +1,12 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/right_arrow_with_translucent_background.xml b/navi-widgets/src/main/res/drawable/right_arrow_with_translucent_background.xml new file mode 100644 index 0000000000..83e9344691 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/right_arrow_with_translucent_background.xml @@ -0,0 +1,13 @@ + + + + diff --git a/navi-widgets/src/main/res/drawable/rounded_negative_button_bg.xml b/navi-widgets/src/main/res/drawable/rounded_negative_button_bg.xml new file mode 100644 index 0000000000..87a2faebb0 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/rounded_negative_button_bg.xml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/tag_background.xml b/navi-widgets/src/main/res/drawable/tag_background.xml new file mode 100644 index 0000000000..e8b45c6a91 --- /dev/null +++ b/navi-widgets/src/main/res/drawable/tag_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/drawable/umbrella_hospital.xml b/navi-widgets/src/main/res/drawable/umbrella_hospital.xml new file mode 100644 index 0000000000..34590c838b --- /dev/null +++ b/navi-widgets/src/main/res/drawable/umbrella_hospital.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navi-widgets/src/main/res/layout/centred_title_subtitle_desc_widget.xml b/navi-widgets/src/main/res/layout/centred_title_subtitle_desc_widget.xml new file mode 100644 index 0000000000..858a39018b --- /dev/null +++ b/navi-widgets/src/main/res/layout/centred_title_subtitle_desc_widget.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/layout/checkpoint_layout_unvisited.xml b/navi-widgets/src/main/res/layout/checkpoint_layout_unvisited.xml new file mode 100644 index 0000000000..de4b3e8345 --- /dev/null +++ b/navi-widgets/src/main/res/layout/checkpoint_layout_unvisited.xml @@ -0,0 +1,50 @@ + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/layout/checkpoint_layout_visited.xml b/navi-widgets/src/main/res/layout/checkpoint_layout_visited.xml new file mode 100644 index 0000000000..054a9530d5 --- /dev/null +++ b/navi-widgets/src/main/res/layout/checkpoint_layout_visited.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/layout/expandable_faqs_widget_layout.xml b/navi-widgets/src/main/res/layout/expandable_faqs_widget_layout.xml new file mode 100644 index 0000000000..6114b827b2 --- /dev/null +++ b/navi-widgets/src/main/res/layout/expandable_faqs_widget_layout.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/layout/faq_list_single_item.xml b/navi-widgets/src/main/res/layout/faq_list_single_item.xml new file mode 100644 index 0000000000..4aaf0f010e --- /dev/null +++ b/navi-widgets/src/main/res/layout/faq_list_single_item.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navi-widgets/src/main/res/layout/footer_with_title_and_button.xml b/navi-widgets/src/main/res/layout/footer_with_title_and_button.xml new file mode 100644 index 0000000000..107e6993de --- /dev/null +++ b/navi-widgets/src/main/res/layout/footer_with_title_and_button.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + +