Untitled

mail@pastecode.io avatar
unknown
kotlin
2 months ago
16 kB
2
Indexable
Never
package com.mse.mseapp.features.home

import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.os.bundleOf
import androidx.navigation.NavController
import androidx.navigation.NavGraph
import androidx.navigation.NavOptions
import androidx.navigation.ui.setupWithNavController
import com.google.android.play.core.review.ReviewManagerFactory
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.moneysavingexpert.core.viewmodel.ReviewRequestViewModel
import com.moneysavingexpert.core.viewmodel.utils.observeEvent
import com.moneysavingexpert.core.viewmodel.utils.observeModel
import com.mse.mseapp.R
import com.mse.mseapp.analytics.models.AnalyticsEventName
import com.mse.mseapp.core.home.AppNavigationTarget
import com.mse.mseapp.core.home.AppNavigationTarget.ChatbotTab
import com.mse.mseapp.core.home.AppNavigationTarget.MSETab
import com.mse.mseapp.core.home.AppNavigationTarget.MyMSETab
import com.mse.mseapp.core.home.AppNavigationTarget.ToolsTab
import com.mse.mseapp.databinding.ActivityHomeBinding
import com.mse.mseapp.extensions.findChildNavController
import com.mse.mseapp.extensions.windowContentView
import com.mse.mseapp.features.content.ContentActivity
import com.mse.mseapp.features.content.SavingContentAfterAuthViewModel
import com.mse.mseapp.features.content.saving.UpdateContentDialog
import com.mse.mseapp.features.home.chatbot.ChatbotInfoBottomSheet
import com.mse.mseapp.features.home.chatbot.ChatbotViewModel
import com.mse.mseapp.features.home.chatbot.composables.ChatbotHighlight
import com.mse.mseapp.features.home.composables.HomeScreenBanner
import com.mse.mseapp.features.home.forcedupdate.ForcedUpdateScreen
import com.mse.mseapp.features.home.manualbillentrymodal.ManualBillEntryModal
import com.mse.mseapp.features.home.ssoaactionmodal.HomeScreenPromotionalItemsViewModel
import com.mse.mseapp.features.home.ssoaactionmodal.SSOActionModal
import com.mse.mseapp.features.notifications.reprompt.NotificationRepromptBottomSheet
import com.mse.mseapp.features.pin.BaseTimerActivity
import com.mse.mseapp.features.signup.AuthFlowActivity
import com.mse.mseapp.utils.ui.HomeActivityTabs
import com.mse.mseapp.utils.ui.billBuster
import com.mse.mseapp.utils.ui.homeActivityBottomTab
import com.mse.mseapp.utils.ui.launchingTool
import com.mse.mseapp.utils.ui.savedContent
import com.mse.mseapp.utils.ui.startHomeActivityInSpecificTab
import com.mse.mseapp.utils.webview.models.UtmCampaignEntryPoint
import org.koin.androidx.viewmodel.ext.android.viewModel

class HomeActivity : BaseTimerActivity() {

    private lateinit var binding: ActivityHomeBinding
    private val viewModel: HomeActivityViewModel by viewModel()
    private val savingContentAfterAuthViewModel: SavingContentAfterAuthViewModel by viewModel()
    private val reviewRequestViewModel: ReviewRequestViewModel by viewModel()
    private val homescreenPromoViewModel: HomeScreenPromotionalItemsViewModel by viewModel()
    private val chatbotViewModel: ChatbotViewModel by viewModel()

    private val navController: NavController? by lazy {
        findChildNavController(R.id.home_navigation_container)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    @RequiresApi(Build.VERSION_CODES.S)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(binding.root)
        buildAppBannerForDisplay()
        observeModels()
        navController?.let {
            val navGraph = it.navInflater.inflate(R.navigation.home_nav)
            binding.bottomNavigation.setupWithNavController(it)
            setStartDestinationBasedOnFlaggedContent(navGraph)
        }
        binding.bottomNavigation.visibility = View.VISIBLE
        setBottomMenuItem()
        handleDeeplink()
        viewModel.isAppUpToDate()
        viewModel.onCreate()
    }

    override fun onResume() {
        super.onResume()
        savingContentAfterAuthViewModel.onContentSavedAfterAuth()
        reviewRequestViewModel.onReturnToScreen()
        homescreenPromoViewModel.onResume()
        viewModel.onResume()
    }

    override fun onPause() {
        super.onPause()
        viewModel.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        viewModel.onDestroy()
    }

    private fun handleDeeplink() {
        intent.extras?.apply {
            when {
                containsKey(MSE_TAB_KEY) -> navController?.navigate(R.id.mse_home_content)
                containsKey(MY_MSE_TAB_KEY) -> navController?.navigate(R.id.my_mse_home_content)
                containsKey(TOOLS_TAB_KEY) -> navController?.navigate(R.id.tools_home_content)
                containsKey(CHATBOT_TAB_KEY) -> navController?.navigate(R.id.bot_home_content)
                containsKey(ARTICLE_URL) -> launchContentActivityForLink(
                    link = getString(
                        ARTICLE_URL,
                        ""
                    ),
                    refererUrl = getString(REFERER_URL, "")
                )
            }
        }
    }

    private fun observeModels() {
        observeEvent(savingContentAfterAuthViewModel.showSavingSuccessMessage) {
            windowContentView?.apply {
                UpdateContentDialog.showSavedDialog(this) {
                    startHomeActivityInSpecificTab(
                        this@HomeActivity,
                        HomeActivityTabs.myMse,
                        savedContent
                    )
                }
            }
            savingContentAfterAuthViewModel.clearCache()
        }

        observeEvent(reviewRequestViewModel.requestReviewFromUser) {
            requestReview()
        }

        observeModel(homescreenPromoViewModel.showSSOActionModal) {
            launchSSOActionModal()
        }

        observeModel(homescreenPromoViewModel.showChatbotHighlight) {
            launchChatbotHighlight()
        }

        observeModel(homescreenPromoViewModel.dismissChatbotHighlight) {
            binding.chatbotHighlightContainer.visibility = View.GONE
        }

        observeEvent(chatbotViewModel.launchInfoPanelEvent) {
            launchChatbotInformationDialog()
        }

        observeEvent(homescreenPromoViewModel.showNotificationRepromptDialog) {
            launchNotificationRepromptDialog()
        }

        observeModel(viewModel.shouldShowForceUpdate) {
            if (it)
                ForcedUpdateScreen().show(
                    this@HomeActivity.supportFragmentManager,
                    "ForcedUpdateScreen"
                )
        }

        observeModel(homescreenPromoViewModel.showManualBillAdvert) {
            launchManualBillEntryAdvert()
        }

        observeModel(homescreenPromoViewModel.launchToRegistration) {
            startActivity(Intent(this, AuthFlowActivity::class.java))
        }

        observeModel(homescreenPromoViewModel.launchToBillBuster) {
            navController?.graph?.apply {
                val toolsBundle =
                    bundleOf(launchingTool to billBuster)
                navController?.navigate(R.id.my_mse_home_content, toolsBundle)
            }
        }
    }

    private fun requestReview() {
        Log.d(HomeActivity::class.simpleName, "Attempting to request review from user")

        val manager = ReviewManagerFactory.create(this@HomeActivity)
        val request = manager.requestReviewFlow()
        request.addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val reviewInfo = task.result
                manager.launchReviewFlow(this@HomeActivity, reviewInfo)
                reviewRequestViewModel.onSendingEvent(AnalyticsEventName.request_user_review)
            } else {
                Log.e(
                    HomeActivity::class.simpleName,
                    "There was an issue, and the issue was ${task.exception}"
                )
            }
            reviewRequestViewModel.isRequestingReview = false
        }
    }

    private fun setBottomMenuItem() {
        val (myMse, mse, hub, bot) = viewModel.getDisplayableBottomTabs()

        // Only remove the MSE tab if there is another tab for the user to use.
        // If all flags are disabled then the MSE tab should be shown as a default.
        if (!mse && (myMse || hub || bot)) {
            removeTabIfNotAvailable(mse, R.id.mse_home_content)
        }
        // Decision to turn off these tabs is purely based on whether their feature flag is off or not.
        removeTabIfNotAvailable(myMse, R.id.my_mse_home_content)
        removeTabIfNotAvailable(hub, R.id.tools_home_content)
        removeTabIfNotAvailable(bot, R.id.bot_home_content)
    }

    private fun setStartDestinationBasedOnFlaggedContent(
        navGraph: NavGraph?
    ) {
        val (myMse, mse, hub, bot) = viewModel.getDisplayableBottomTabs()
        navGraph?.apply {
            when {
                mse -> setStartDestination(this, R.id.mse_home_content)
                myMse -> setStartDestination(this, R.id.my_mse_home_content)
                hub -> setStartDestination(this, R.id.tools_home_content)
                bot -> setStartDestination(this, R.id.bot_home_content)
                else -> setStartDestination(this, R.id.mse_home_content)
            }
        }
    }

    private fun handleIntent(intent: Intent?) {
        intent?.let { navController?.graph?.navigateToHomeTabFromIntent(it) }
    }

    private fun NavGraph.navigateToHomeTabFromIntent(intent: Intent) {
        intent
            .extras
            ?.getString(homeActivityBottomTab)
            ?.let {
                when (it) {
                    HomeActivityTabs.myMse -> {
                        val toolsBundle =
                            bundleOf(launchingTool to intent.extras?.getString(launchingTool))
                        setStartDestination(this, R.id.my_mse_home_content)
                        navController?.navigate(R.id.my_mse_home_content, toolsBundle)
                    }

                    HomeActivityTabs.tools -> navController?.navigate(R.id.tools_home_content)

                    HomeActivityTabs.bot -> {
                        setStartDestination(this, R.id.bot_home_content)
                        navController?.navigate(R.id.bot_home_content)
                    }

                    else -> {
                        navController?.navigate(R.id.mse_home_content)
                    }
                }
                // TODO: check if fine
//            } ?: setStartDestination(this, R.id.mse_home_content)
            } ?: navController?.navigate(R.id.mse_home_content)
    }

    private fun setStartDestination(navGraph: NavGraph?, destination: Int) {
        navGraph?.apply {
            setStartDestination(destination)
            navController?.graph = this
            try {
                binding.bottomNavigation.selectedItemId = destination
            } catch (nullPointer: NullPointerException) {
                FirebaseCrashlytics.getInstance().recordException(nullPointer)
            }
        }
    }

    private fun removeTabIfNotAvailable(isAvailable: Boolean, tabId: Int) {
        if (!isAvailable) binding.bottomNavigation.menu.removeItem(tabId)
    }

    private fun launchContentActivityForLink(link: String, refererUrl: String) {
        ContentActivity.startContentActivity(
            context = this@HomeActivity,
            contentUrl = link,
            refererUrl = refererUrl,
            entryPoint = UtmCampaignEntryPoint.HOME
        )
    }

    private fun launchSSOActionModal() {
        SSOActionModal
            .newInstance()
            .show(this.supportFragmentManager)
    }

    private fun launchChatbotHighlight() {
        binding.chatbotHighlight.apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                ChatbotHighlight(
                    onTryTapped = {
                        navController?.navigate(
                            R.id.bot_home_content,
                            null,
                            NavOptions.Builder()
                                .setPopUpTo(R.id.mse_home_content, true)
                                .build()
                        )
                        homescreenPromoViewModel.onDismissChatbotHighlight()
                    },
                    onCancelTapped = { homescreenPromoViewModel.onDismissChatbotHighlight() }
                )
            }
        }
        binding.chatbotHighlightContainer.visibility = View.VISIBLE
    }

    private fun launchChatbotInformationDialog() {
        ChatbotInfoBottomSheet
            .newInstance()
            .show(supportFragmentManager, "ChatbotInfoModal")
    }

    private fun launchNotificationRepromptDialog() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            NotificationRepromptBottomSheet
                .newInstance()
                .show(supportFragmentManager, "NotificationReprompt")
        }
    }

    private fun launchManualBillEntryAdvert() {
        ManualBillEntryModal
            .newInstance()
            .show(supportFragmentManager, "ManualBillEntryAdvert")
    }

    private fun buildAppBannerForDisplay() {
        binding.appBannerContainer.apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                HomeScreenBanner(context, viewModel)
            }
        }
    }

    companion object {

        const val MSE_TAB_KEY = "MSE_TAB_KEY"
        const val MY_MSE_TAB_KEY = "MY_MSE_TAB_KEY"
        const val TOOLS_TAB_KEY = "TOOLS_TAB_KEY"
        const val CHATBOT_TAB_KEY = "CHATBOT_TAB_KEY"
        const val ARTICLE_URL = "ARTICLE_URL"
        const val REFERER_URL = "REFERER_URL"

        fun startActivityFromLink(context: Context, tab: AppNavigationTarget) {
            val bundle = Bundle()
                .apply {
                    when (tab) {
                        is MyMSETab -> putSerializable(MY_MSE_TAB_KEY, tab.segment)
                        is MSETab -> putSerializable(MSE_TAB_KEY, tab.segment)
                        is ToolsTab -> putSerializable(TOOLS_TAB_KEY, tab.card)
                        is ChatbotTab -> putSerializable(CHATBOT_TAB_KEY, "chatbot")
                        else -> {}
                    }
                }

            Intent(context, HomeActivity::class.java).run {
                flags =
                    Intent.FLAG_ACTIVITY_REORDER_TO_FRONT or
                            Intent.FLAG_ACTIVITY_CLEAR_TASK or
                            Intent.FLAG_ACTIVITY_NEW_TASK
                putExtras(bundle)
                context.startActivity(this)
            }
        }

        fun startActivityWithArticle(
            context: Context,
            articleUrl: String,
            refererUrl: String? = null
        ) {
            context
                .startActivity(
                    Intent(context, HomeActivity::class.java)
                        .apply {
                            flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT or
                                    Intent.FLAG_ACTIVITY_CLEAR_TASK or
                                    Intent.FLAG_ACTIVITY_NEW_TASK
                            val bundle = Bundle()
                                .apply {
                                    putString(ARTICLE_URL, articleUrl)
                                    putString(REFERER_URL, refererUrl)
                                }
                            putExtras(bundle)
                        }
                )
        }

        fun launchAsNavigationStart(context: Context) {
            context.startActivity(
                Intent(
                    context,
                    HomeActivity::class.java
                ).apply {
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                }
            )
        }
    }
}
Leave a Comment