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