From 5f5abdf51a22c3ae7ee90729b93a6b3a68d5e0f3 Mon Sep 17 00:00:00 2001
From: Kamal Bramwell <kamal@elixxir.io>
Date: Tue, 2 Aug 2022 18:52:00 -0400
Subject: [PATCH] Handled navigation to search screen from connection
 invitation

---
 .../messenger/search/FactSearchFragment.kt    | 10 +++++++++
 .../messenger/search/UserSearchFragment.kt    | 10 +++++++++
 .../messenger/search/UserSearchViewModel.kt   | 11 ++++++++++
 .../splash/SplashScreenPlaceholderActivity.kt | 22 +++++++++++++++++++
 .../xxlabs/messenger/ui/main/MainActivity.kt  | 17 ++++++++++++++
 app/src/main/res/navigation/nav_main.xml      | 14 ++++++++++++
 6 files changed, 84 insertions(+)

diff --git a/app/src/main/java/io/xxlabs/messenger/search/FactSearchFragment.kt b/app/src/main/java/io/xxlabs/messenger/search/FactSearchFragment.kt
index 2a2f1255..6c4deddf 100644
--- a/app/src/main/java/io/xxlabs/messenger/search/FactSearchFragment.kt
+++ b/app/src/main/java/io/xxlabs/messenger/search/FactSearchFragment.kt
@@ -121,6 +121,16 @@ class UsernameSearchFragment : FactSearchFragment() {
     }
 
     override fun getSearchTabUi(): FactSearchUi = searchViewModel.usernameSearchUi
+
+    override fun onResume() {
+        super.onResume()
+        searchViewModel.invitationFrom.observe(viewLifecycleOwner) { username ->
+            username?.let {
+                onSearchClicked(it)
+                searchViewModel.onInvitationHandled()
+            }
+        }
+    }
 }
 
 class EmailSearchFragment : FactSearchFragment() {
diff --git a/app/src/main/java/io/xxlabs/messenger/search/UserSearchFragment.kt b/app/src/main/java/io/xxlabs/messenger/search/UserSearchFragment.kt
index eaebf5cd..02beb4e7 100644
--- a/app/src/main/java/io/xxlabs/messenger/search/UserSearchFragment.kt
+++ b/app/src/main/java/io/xxlabs/messenger/search/UserSearchFragment.kt
@@ -52,6 +52,9 @@ class UserSearchFragment : RequestsFragment() {
     override val navController: NavController by lazy {
         findNavController()
     }
+    private val invitationUsername: String? by lazy {
+        UserSearchFragmentArgs.fromBundle(requireArguments()).username
+    }
 
     override fun onAttach(context: Context) {
         super.onAttach(context)
@@ -161,9 +164,16 @@ class UserSearchFragment : RequestsFragment() {
 
     override fun onStart() {
         super.onStart()
+        handleInvitation()
         observeUi()
     }
 
+    private fun handleInvitation() {
+        invitationUsername?.let {
+            searchViewModel.onInvitationReceived(it)
+        }
+    }
+
     private fun observeUi() {
         searchViewModel.udSearchUi.observe(viewLifecycleOwner) { state ->
             binding.ui = state
diff --git a/app/src/main/java/io/xxlabs/messenger/search/UserSearchViewModel.kt b/app/src/main/java/io/xxlabs/messenger/search/UserSearchViewModel.kt
index e5f40eaa..0937eb9b 100644
--- a/app/src/main/java/io/xxlabs/messenger/search/UserSearchViewModel.kt
+++ b/app/src/main/java/io/xxlabs/messenger/search/UserSearchViewModel.kt
@@ -206,6 +206,9 @@ class UserSearchViewModel @Inject constructor(
 
     private var searchJob: Job? = null
 
+    val invitationFrom: LiveData<String?> by ::_invitationFrom
+    private val _invitationFrom = MutableLiveData<String?>(null)
+
     init {
         showNewUserPopups()
     }
@@ -271,6 +274,14 @@ class UserSearchViewModel @Inject constructor(
         repo.enableDummyTraffic(enabled)
     }
 
+    fun onInvitationReceived(username: String) {
+        _invitationFrom.value = username
+    }
+
+    fun onInvitationHandled() {
+        _invitationFrom.value = null
+    }
+
     suspend fun onUsernameSearch(username: String?): Flow<List<RequestItem>> {
         _usernameResults.value = listOf()
         val factQuery = FactQuery.UsernameQuery(username)
diff --git a/app/src/main/java/io/xxlabs/messenger/ui/intro/splash/SplashScreenPlaceholderActivity.kt b/app/src/main/java/io/xxlabs/messenger/ui/intro/splash/SplashScreenPlaceholderActivity.kt
index 53913e0c..68bc8605 100644
--- a/app/src/main/java/io/xxlabs/messenger/ui/intro/splash/SplashScreenPlaceholderActivity.kt
+++ b/app/src/main/java/io/xxlabs/messenger/ui/intro/splash/SplashScreenPlaceholderActivity.kt
@@ -19,7 +19,9 @@ import io.xxlabs.messenger.support.isMockVersion
 import io.xxlabs.messenger.support.util.Utils
 import io.xxlabs.messenger.ui.base.BaseInjectorActivity
 import io.xxlabs.messenger.ui.main.MainActivity
+import io.xxlabs.messenger.ui.main.MainActivity.Companion.INTENT_INVITATION
 import io.xxlabs.messenger.ui.main.MainActivity.Companion.INTENT_NOTIFICATION_CLICK
+import timber.log.Timber
 import javax.inject.Inject
 
 class SplashScreenPlaceholderActivity : BaseInjectorActivity() {
@@ -54,6 +56,26 @@ class SplashScreenPlaceholderActivity : BaseInjectorActivity() {
     }
 
     private fun handleIntent(intent: Intent) {
+        if (Intent.ACTION_VIEW == intent.action) {
+            // Implicit Intent from an invitation link
+            intent.data?.getQueryParameter("username")?.let { username ->
+                invitationIntent(username)
+            }
+        } else notificationIntent(intent)
+    }
+
+    private fun invitationIntent(username: String) {
+        // Invitations can only be handled if the user has an account.
+        if (preferencesRepository.name.isNotEmpty()) {
+            val intent = Intent(this, MainActivity::class.java).apply {
+                putExtra(INTENT_INVITATION, username)
+            }
+            startActivity(intent)
+            finish()
+        }
+    }
+
+    private fun notificationIntent(intent: Intent) {
         // Pass this intent on to MainActivity.
         mainIntent = intent.getBundleExtra(INTENT_NOTIFICATION_CLICK)?.let {
             Intent(
diff --git a/app/src/main/java/io/xxlabs/messenger/ui/main/MainActivity.kt b/app/src/main/java/io/xxlabs/messenger/ui/main/MainActivity.kt
index 01678bd8..66267999 100755
--- a/app/src/main/java/io/xxlabs/messenger/ui/main/MainActivity.kt
+++ b/app/src/main/java/io/xxlabs/messenger/ui/main/MainActivity.kt
@@ -19,6 +19,7 @@ import androidx.lifecycle.*
 import androidx.lifecycle.Observer
 import androidx.navigation.NavController
 import androidx.navigation.Navigation
+import androidx.navigation.findNavController
 import androidx.navigation.ui.onNavDestinationSelected
 import com.bumptech.glide.Glide
 import com.google.android.material.shape.CornerFamily
@@ -164,8 +165,23 @@ class MainActivity : MediaProviderActivity(), SnackBarActivity, CustomToastActiv
 
     private fun handleIntent(intent: Intent) {
         intent.getBundleExtra(INTENT_NOTIFICATION_CLICK)?.let {
+            // PendingIntent from notifications
             handleNotification(it)
+            return
         }
+
+        intent.getStringExtra(INTENT_INVITATION)?.let { username ->
+            // Implicit intent from an invitation link
+            invitationIntent(username)
+            return
+        }
+    }
+
+    private fun invitationIntent(username: String) {
+        val userSearch = NavMainDirections.actionGlobalConnectionInvitation().apply {
+            this.username = username
+        }
+        mainNavController.navigateSafe(userSearch)
     }
 
     private fun handleNotification(bundle: Bundle) {
@@ -811,6 +827,7 @@ class MainActivity : MediaProviderActivity(), SnackBarActivity, CustomToastActiv
         const val INTENT_PRIVATE_CHAT = "private_message"
         const val INTENT_GROUP_CHAT = "group_message"
         const val INTENT_REQUEST = "request"
+        const val INTENT_INVITATION = "invitation"
 
         private var activeInstances = 0
         override fun activeInstancesCount(): Int {
diff --git a/app/src/main/res/navigation/nav_main.xml b/app/src/main/res/navigation/nav_main.xml
index 9953388f..b5e8db61 100644
--- a/app/src/main/res/navigation/nav_main.xml
+++ b/app/src/main/res/navigation/nav_main.xml
@@ -320,6 +320,11 @@
             app:exitAnim="@anim/slide_out_left"
             app:popEnterAnim="@anim/slide_in_left"
             app:popExitAnim="@anim/slide_out_right" />
+        <argument
+            android:name="username"
+            app:argType="string"
+            app:nullable="true"
+            android:defaultValue="@null" />
     </fragment>
 
     <fragment
@@ -354,6 +359,15 @@
         android:label="UdProfileFragment"
         tools:layout="@layout/fragment_ud_profile" />
 
+    <action
+        android:id="@+id/action_global_connection_invitation"
+        app:destination="@id/udPrivateSearchFragment"
+        app:enterAnim="@anim/slide_in_right"
+        app:exitAnim="@anim/slide_out_left"
+        app:popEnterAnim="@anim/slide_in_left"
+        app:popExitAnim="@anim/slide_out_right" />
+
+
     <action
         android:id="@+id/action_global_contact_invitation"
         app:destination="@id/contactInvitationFragment"
-- 
GitLab