diff --git a/app/build.gradle b/app/build.gradle index 6829c7bfd9..18a4042b7e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -163,6 +163,7 @@ dependencies { playImplementation libraries.playServicesAuth playImplementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') { transitive = true } playImplementation('com.crashlytics.sdk.android:answers:1.4.3@aar') { transitive = true } + playImplementation libraries.dynamiclinks testImplementation libraries.junit testImplementation libraries.truth diff --git a/app/google-services.json b/app/google-services.json index 19eb910d1b..6d83ec0393 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -70,4 +70,4 @@ } ], "configuration_version": "1" -} \ No newline at end of file +} diff --git a/app/src/foss/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt b/app/src/foss/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt new file mode 100644 index 0000000000..84c64b5263 --- /dev/null +++ b/app/src/foss/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt @@ -0,0 +1,17 @@ +package chat.rocket.android.dynamiclinks + +import android.content.Context +import android.content.Intent +import android.net.Uri +import javax.inject.Inject + +class DynamicLinksForFirebase @Inject constructor(private val context: Context) : DynamicLinks { + + override fun getDynamicLink(intent: Intent, deepLinkCallback: (Uri?) -> Unit? ) { + deepLinkCallback(null) + } + + override fun createDynamicLink(username: String, server: String, deepLinkCallback: (String?) -> Unit?) { + deepLinkCallback(null) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bcf973ce03..b00bb29ada 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,7 @@ @@ -41,13 +42,9 @@ - - + @@ -58,7 +55,7 @@ + android:windowSoftInputMode="adjustResize|stateAlwaysHidden"/> @Inject lateinit var presenter: AuthenticationPresenter + @Inject + lateinit var dynamicLinksManager: DynamicLinksForFirebase val job = Job() override fun onCreate(savedInstanceState: Bundle?) { @@ -34,7 +39,44 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { super.onCreate(savedInstanceState) setContentView(R.layout.activity_authentication) setupToolbar() - loadCredentials() + + processIncomingIntent(intent) + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + intent?.let { + processIncomingIntent(it) + } + } + + private fun processIncomingIntent(intent: Intent) { + if (intent.isSupportedLink()) { + val uri = intent.data + if (uri.isDynamicLink()) { + resolveDynamicLink(intent) + } else { + uri.getDeepLinkInfo()?.let{ + routeDeepLink(it) + } .ifNull { + routeNoLink() + } + } + } else { + routeNoLink() + } + } + + private fun resolveDynamicLink(intent: Intent) { + var deepLinkCallback = { returnedUri: Uri? -> + if (returnedUri == null) { + routeNoLink() + } else { + returnedUri?.getDeepLinkInfo()?.let { + routeDeepLink(it) + } } + } + dynamicLinksManager.getDynamicLink(intent, deepLinkCallback) } private fun setupToolbar() { @@ -68,42 +110,30 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { return super.onOptionsItemSelected(item) } - private fun loadCredentials() { - intent.getLoginDeepLinkInfo()?.let { - showServerFragment(it) - }.ifNull { - val newServer = intent.getBooleanExtra(INTENT_ADD_NEW_SERVER, false) - presenter.loadCredentials(newServer) { isAuthenticated -> + private fun routeDeepLink(deepLinkInfo: DeepLinkInfo) { + if (Constants.WIDECHAT) + presenter.loadCredentials(false) { isAuthenticated -> if (isAuthenticated) { - showChatList() + presenter.toChatList(deepLinkInfo) } else { - showOnBoardingFragment() + presenter.saveDeepLinkInfo(deepLinkInfo) + presenter.toOnBoarding() } } - } - } - - private fun showOnBoardingFragment() { - addFragment( - ScreenViewEvent.OnBoarding.screenName, - R.id.fragment_container, - allowStateLoss = true - ) { - chat.rocket.android.authentication.onboarding.ui.newInstance() - } + else + presenter.toSignInToYourServer(deepLinkInfo) } - private fun showServerFragment(deepLinkInfo: LoginDeepLinkInfo) { - addFragment( - ScreenViewEvent.Server.screenName, - R.id.fragment_container, - allowStateLoss = true - ) { - chat.rocket.android.authentication.server.ui.newInstance() + private fun routeNoLink() { + val newServer = intent.getBooleanExtra(INTENT_ADD_NEW_SERVER, false) + presenter.loadCredentials(newServer) { isAuthenticated -> + if (isAuthenticated) { + presenter.toChatList() + } else { + presenter.toOnBoarding() + } } } - - private fun showChatList() = presenter.toChatList() } const val INTENT_ADD_NEW_SERVER = "INTENT_ADD_NEW_SERVER" @@ -113,4 +143,4 @@ fun Context.newServerIntent(): Intent { putExtra(INTENT_ADD_NEW_SERVER, true) flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK } -} \ No newline at end of file +} diff --git a/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt b/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt index 828283a6af..2e91a80b18 100644 --- a/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt +++ b/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt @@ -10,8 +10,6 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.CheckBox -import android.widget.RadioGroup import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SearchView import androidx.core.view.isVisible @@ -46,8 +44,9 @@ import javax.inject.Inject // WIDECHAT import android.graphics.Color -import android.widget.ImageView -import android.widget.TextView +import android.widget.* +import chat.rocket.android.authentication.domain.model.DeepLinkInfo +import chat.rocket.android.chatrooms.adapter.model.RoomUiModel import chat.rocket.android.helper.UserHelper import chat.rocket.android.profile.ui.ProfileFragment import chat.rocket.android.server.domain.GetCurrentServerInteractor @@ -90,14 +89,16 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { private var searchCloseButton: ImageView? = null private var profileButton: SimpleDraweeView? = null private var onlineStatusButton:ImageView?=null + private var deepLinkInfo: DeepLinkInfo? = null // handles that recurring connection status bug in widechat private var currentlyConnected: Boolean? = false companion object { - fun newInstance(chatRoomId: String? = null): ChatRoomsFragment { + fun newInstance(chatRoomId: String? = null, deepLinkInfo: DeepLinkInfo? = null): ChatRoomsFragment { return ChatRoomsFragment().apply { arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) + putParcelable(Constants.DEEP_LINK_INFO, deepLinkInfo) } } } @@ -114,6 +115,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { presenter.loadChatRoom(it) chatRoomId = null } + deepLinkInfo = bundle.getParcelable(Constants.DEEP_LINK_INFO) } } @@ -141,12 +143,14 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel = ViewModelProviders.of(this, factory).get(ChatRoomsViewModel::class.java) subscribeUi() - setupToolbar() setupFab() + deepLinkInfo?.let { + processDeepLink(it) + } + deepLinkInfo = null analyticsManager.logScreenView(ScreenViewEvent.ChatRooms) } @@ -515,4 +519,38 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { transaction?.addToBackStack("contactsFragment")?.commit(); } } + + fun processDeepLink(deepLinkInfo: DeepLinkInfo) { + + val username = deepLinkInfo.roomName + username.ifNotNullNorEmpty { + val localRooms = viewModel.getChatRoomOfUsernameDB(username!!) + val filteredLocalRooms = localRooms.filter { itemHolder -> itemHolder.data is RoomUiModel && (itemHolder.data as RoomUiModel).username == username } + + if (filteredLocalRooms.isNotEmpty()) { + presenter.loadChatRoom(filteredLocalRooms.first().data as RoomUiModel) + } else { + //check from spotlight when connected + val statusLiveData = viewModel.getStatus() + statusLiveData.observe(viewLifecycleOwner, object: Observer{ + override fun onChanged(status: State?) { + if (status is State.Connected) { + val rooms = viewModel.getChatRoomOfUsernameSpotlight(username) + val filteredRooms = rooms?.filter { itemHolder -> itemHolder.data is RoomUiModel && (itemHolder.data as RoomUiModel).username == username } + + filteredRooms?.let { + if (filteredRooms.isNotEmpty()) { + presenter.loadChatRoom(filteredRooms.first().data as RoomUiModel) + } else { + Toast.makeText(context, "User not found or No internet connection", Toast.LENGTH_SHORT).show() + } + } + + statusLiveData.removeObserver(this) + } + } + }) + } + } + } } diff --git a/app/src/main/java/chat/rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt b/app/src/main/java/chat/rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt index de2a9217df..086d23999f 100644 --- a/app/src/main/java/chat/rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt +++ b/app/src/main/java/chat/rocket/android/chatrooms/viewmodel/ChatRoomsViewModel.kt @@ -83,6 +83,20 @@ class ChatRoomsViewModel( } } + fun getChatRoomOfUsernameDB(string: String): List> { + val rooms = async(CommonPool) { + return@async repository.search(string).let { mapper.map(it, showLastMessage = showLastMessage) } + } + return runBlocking { rooms.await() } + } + + fun getChatRoomOfUsernameSpotlight(string: String): List>? { + val rooms = async(CommonPool) { + return@async spotlight(string)?.let { mapper.map(it, showLastMessage = showLastMessage) } + } + return runBlocking { rooms.await() } + } + private suspend fun spotlight(query: String): SpotlightResult? { return try { retryIO { client.spotlight(query) } diff --git a/app/src/main/java/chat/rocket/android/contacts/ContactsFragment.kt b/app/src/main/java/chat/rocket/android/contacts/ContactsFragment.kt index fe8fc83924..64543379f1 100644 --- a/app/src/main/java/chat/rocket/android/contacts/ContactsFragment.kt +++ b/app/src/main/java/chat/rocket/android/contacts/ContactsFragment.kt @@ -44,20 +44,23 @@ import javax.inject.Inject * Load a list of contacts in a recycler view */ class ContactsFragment : Fragment() { + @Inject lateinit var dbFactory: DatabaseManagerFactory + @Inject lateinit var serverInteractor: GetCurrentServerInteractor + private var recyclerView :RecyclerView? = null private var emptyTextView: TextView? = null - private val MY_PERMISSIONS_REQUEST_RW_CONTACTS = 0 - /** * The list of contacts to load in the recycler view */ private var contactArrayList: ArrayList = ArrayList() + private val MY_PERMISSIONS_REQUEST_RW_CONTACTS = 0 + private var searchView: SearchView? = null private var sortView: MenuItem? = null private var searchIcon: ImageView? = null diff --git a/app/src/main/java/chat/rocket/android/contacts/adapter/ContactRecyclerViewAdapter.kt b/app/src/main/java/chat/rocket/android/contacts/adapter/ContactRecyclerViewAdapter.kt index 0cbe7a6bef..0bdf135847 100644 --- a/app/src/main/java/chat/rocket/android/contacts/adapter/ContactRecyclerViewAdapter.kt +++ b/app/src/main/java/chat/rocket/android/contacts/adapter/ContactRecyclerViewAdapter.kt @@ -100,12 +100,7 @@ class ContactRecyclerViewAdapter( } private fun shareApp() { - with(Intent(Intent.ACTION_SEND)) { - type = "text/plain" - putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.msg_check_this_out)) - putExtra(Intent.EXTRA_TEXT, context.getString(R.string.play_store_link)) - context.startActivity(Intent.createChooser(this, context.getString(R.string.msg_share_using))) - } + context.presenter.shareViaApp(context) } companion object { diff --git a/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt b/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt index 1a54df6d41..50bc37f749 100644 --- a/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt +++ b/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt @@ -19,6 +19,7 @@ import chat.rocket.android.dagger.qualifier.ForAuthentication import chat.rocket.android.dagger.qualifier.ForMessages import chat.rocket.android.db.DatabaseManager import chat.rocket.android.db.DatabaseManagerFactory +import chat.rocket.android.dynamiclinks.DynamicLinksForFirebase import chat.rocket.android.helper.MessageParser import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.SharedPreferencesLocalRepository @@ -378,6 +379,12 @@ class AppModule { return AnswersAnalytics() } + @Provides + @Singleton + fun provideDynamicLinkForFirebase(context: Application): DynamicLinksForFirebase { + return DynamicLinksForFirebase(context) + } + @Provides @Singleton fun provideGoogleAnalyticsForFirebase(context: Application): GoogleAnalyticsForFirebase { diff --git a/app/src/main/java/chat/rocket/android/db/ChatRoomDao.kt b/app/src/main/java/chat/rocket/android/db/ChatRoomDao.kt index 2651e3f4df..383a94ba96 100644 --- a/app/src/main/java/chat/rocket/android/db/ChatRoomDao.kt +++ b/app/src/main/java/chat/rocket/android/db/ChatRoomDao.kt @@ -9,7 +9,6 @@ import androidx.room.Transaction import androidx.room.Update import chat.rocket.android.db.model.ChatRoom import chat.rocket.android.db.model.ChatRoomEntity -import chat.rocket.common.model.RoomType @Dao abstract class ChatRoomDao : BaseDao { diff --git a/app/src/main/java/chat/rocket/android/dynamiclinks/DynamicLinks.kt b/app/src/main/java/chat/rocket/android/dynamiclinks/DynamicLinks.kt new file mode 100644 index 0000000000..2576c663c3 --- /dev/null +++ b/app/src/main/java/chat/rocket/android/dynamiclinks/DynamicLinks.kt @@ -0,0 +1,11 @@ +package chat.rocket.android.dynamiclinks + +import android.content.Intent +import android.net.Uri + +interface DynamicLinks { + + fun getDynamicLink(intent: Intent, deepLinkCallback: (Uri?) -> Unit? ) + + fun createDynamicLink(username: String, server: String, deepLinkCallback: (String?) -> Unit?) +} diff --git a/app/src/main/java/chat/rocket/android/helper/Constants.kt b/app/src/main/java/chat/rocket/android/helper/Constants.kt index 6ee5ea52ea..72d0ad6726 100644 --- a/app/src/main/java/chat/rocket/android/helper/Constants.kt +++ b/app/src/main/java/chat/rocket/android/helper/Constants.kt @@ -15,7 +15,9 @@ object Constants { // Use both WIDECHAT and WIDECHAT_DEV switches == true to allow for normal RC login sequence including login to any server const val WIDECHAT = true const val WIDECHAT_DEV = false + const val AVATAR_SHAPE_CIRCLE = true + const val DEEP_LINK_INFO = "deep_link_info" } object ChatRoomsSortOrder { diff --git a/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt b/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt index c149448922..6b9161654a 100644 --- a/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt +++ b/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt @@ -1,6 +1,7 @@ package chat.rocket.android.main.presentation import chat.rocket.android.R +import chat.rocket.android.authentication.domain.model.DeepLinkInfo import chat.rocket.android.authentication.ui.newServerIntent import chat.rocket.android.chatroom.ui.chatRoomIntent import chat.rocket.android.chatrooms.ui.ChatRoomsFragment @@ -18,9 +19,9 @@ import chat.rocket.android.webview.adminpanel.ui.AdminPanelWebViewFragment class MainNavigator(internal val activity: MainActivity) { - fun toChatList(chatRoomId: String? = null) { + fun toChatList(chatRoomId: String? = null, deepLinkInfo: DeepLinkInfo? = null) { activity.addFragment(TAG_CHAT_ROOMS_FRAGMENT, R.id.fragment_container) { - ChatRoomsFragment.newInstance(chatRoomId) + ChatRoomsFragment.newInstance(chatRoomId, deepLinkInfo) } } diff --git a/app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt b/app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt index aa62551b2c..41e8170ac3 100644 --- a/app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt +++ b/app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt @@ -2,17 +2,14 @@ package chat.rocket.android.main.presentation import android.content.Context import android.content.Intent -import android.view.LayoutInflater -import android.widget.EditText -import android.widget.TextView -import androidx.appcompat.app.AlertDialog -import androidx.core.content.ContextCompat.startActivity import chat.rocket.android.R +import chat.rocket.android.authentication.domain.model.DeepLinkInfo import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.db.DatabaseManagerFactory import chat.rocket.android.db.DatabaseManager import chat.rocket.android.db.model.ChatRoomEntity +import chat.rocket.android.dynamiclinks.DynamicLinksForFirebase import chat.rocket.android.emoji.Emoji import chat.rocket.android.emoji.EmojiRepository import chat.rocket.android.emoji.Fitzpatrick @@ -57,6 +54,7 @@ import chat.rocket.core.model.Myself import chat.rocket.common.model.RoomType import kotlinx.coroutines.experimental.channels.Channel import kotlinx.coroutines.experimental.CommonPool +import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.withContext import timber.log.Timber import javax.inject.Inject @@ -92,6 +90,9 @@ class MainPresenter @Inject constructor( tokenView = view, navigator = navigator ) { + @Inject + lateinit var dynamicLinksManager : DynamicLinksForFirebase + private val currentServer = serverInteractor.get()!! private val manager = managerFactory.create(currentServer) private val dbManager = dbManagerFactory.create(currentServer) @@ -100,7 +101,7 @@ class MainPresenter @Inject constructor( private var settings: PublicSettings = getSettingsInteractor.get(serverInteractor.get()!!) private val userDataChannel = Channel() - fun toChatList(chatRoomId: String? = null) = navigator.toChatList(chatRoomId) + fun toChatList(chatRoomId: String? = null, deepLinkInfo: DeepLinkInfo? = null) = navigator.toChatList(chatRoomId, deepLinkInfo) fun openDirectMessageChatRoom(username: String) { @@ -319,38 +320,22 @@ class MainPresenter @Inject constructor( super.logout(userDataChannel) } - /** - * Invite - */ - fun invite(context: Context) { - launchUI(strategy) { - + fun shareViaApp(context: Context){ + launch { //get serverUrl and username val server = serverInteractor.get()!! val account = getAccountInteractor.get(server)!! val userName = account.userName - val defaultMessage = "Hey! I’m on Veranda. If you sign up we can chat for free. \nMy username is “$userName” on server $server " - - //Dialog - val layoutInflater = LayoutInflater.from(context) - val dialogLayout = layoutInflater.inflate(R.layout.invite_dialog, null) - val editText = dialogLayout.findViewById(R.id.invite_text) - editText.setText(defaultMessage, TextView.BufferType.NORMAL) - - AlertDialog.Builder(context) - .setTitle(R.string.invite_label) - .setView(dialogLayout) - .setPositiveButton(R.string.action_invite) { dialog, _ -> - dialog.dismiss() - - //intent - val inviteIntent = Intent() - inviteIntent.action = Intent.ACTION_SEND - inviteIntent.putExtra(Intent.EXTRA_TEXT, editText.text.toString()) - inviteIntent.type = "text/plain" - startActivity(context, inviteIntent, null) - }.show() + var deepLinkCallback = { returnedString: String? -> + with(Intent(Intent.ACTION_SEND)) { + type = "text/plain" + putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.msg_check_this_out)) + putExtra(Intent.EXTRA_TEXT, "Default Invitation Text : $returnedString") + context.startActivity(Intent.createChooser(this, context.getString(R.string.msg_share_using))) + } + } + dynamicLinksManager.createDynamicLink(userName, server, deepLinkCallback) } } diff --git a/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt b/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt index 93d00199e3..c841785c43 100644 --- a/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt +++ b/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt @@ -5,9 +5,9 @@ import android.Manifest import android.app.Activity import android.app.AlertDialog import android.app.ProgressDialog +import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle -import android.text.Layout import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat @@ -15,13 +15,15 @@ import androidx.core.content.ContextCompat import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.fragment.app.Fragment -import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import chat.rocket.android.BuildConfig import chat.rocket.android.R +import chat.rocket.android.authentication.domain.model.DeepLinkInfo +import chat.rocket.android.chatrooms.ui.ChatRoomsFragment +import chat.rocket.android.chatrooms.ui.TAG_CHAT_ROOMS_FRAGMENT import chat.rocket.android.contacts.worker.ContactSyncWorker import chat.rocket.android.main.adapter.AccountsAdapter import chat.rocket.android.main.adapter.Selector @@ -38,6 +40,7 @@ import chat.rocket.android.util.extensions.rotateBy import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.invalidateFirebaseToken import chat.rocket.common.model.UserStatus +import chat.rocket.common.util.ifNull import dagger.android.AndroidInjection import dagger.android.AndroidInjector import dagger.android.DispatchingAndroidInjector @@ -67,12 +70,14 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, private var expanded = false private val headerLayout by lazy { view_navigation.getHeaderView(0) } private var chatRoomId: String? = null + private var deepLinkInfo: DeepLinkInfo? = null private var progressDialog: ProgressDialog? = null private val PERMISSIONS_REQUEST_RW_CONTACTS = 0 override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) + if (Constants.WIDECHAT) { setContentView(R.layout.widechat_activity_main) } else { @@ -81,6 +86,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, refreshPushToken() syncContacts() chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID) + deepLinkInfo = intent.getParcelableExtra(Constants.DEEP_LINK_INFO) presenter.clearNotificationsForChatroom(chatRoomId) presenter.connect() @@ -97,6 +103,21 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, } } + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + intent?.let { + var deepLinkInfo = it.getParcelableExtra(Constants.DEEP_LINK_INFO) + if (deepLinkInfo != null) { + val chatRoomsFragment = supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOMS_FRAGMENT) as ChatRoomsFragment + chatRoomsFragment?.let { + it.processDeepLink(deepLinkInfo) + } .ifNull { + isFragmentAdded = false + } + } + } + } + override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) outState?.putBoolean(CURRENT_STATE, isFragmentAdded) @@ -109,18 +130,16 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, override fun onResume() { supportFragmentManager.popBackStackImmediate("contactsFragment", 1) + super.onResume() //syncContacts() if (!isFragmentAdded) { - presenter.toChatList(chatRoomId) + presenter.toChatList(chatRoomId, deepLinkInfo) + deepLinkInfo = null isFragmentAdded = true } } - override fun onPause() { - super.onPause() - } - override fun onDestroy() { super.onDestroy() if (isFinishing) { diff --git a/app/src/main/java/chat/rocket/android/main/ui/Menu.kt b/app/src/main/java/chat/rocket/android/main/ui/Menu.kt index 2bb6012e22..52385991ed 100644 --- a/app/src/main/java/chat/rocket/android/main/ui/Menu.kt +++ b/app/src/main/java/chat/rocket/android/main/ui/Menu.kt @@ -68,7 +68,6 @@ internal fun MainActivity.onNavDrawerItemSelected(menuItem: MenuItem) { when (menuItem.itemId) { R.id.menu_action_chats-> presenter.toChatList() R.id.menu_action_create_channel -> presenter.toCreateChannel() - R.id.menu_action_invite -> presenter.invite(this) R.id.menu_action_profile -> presenter.toUserProfile() R.id.menu_action_settings -> presenter.toSettings() R.id.menu_action_admin_panel -> presenter.toAdminPanel() diff --git a/app/src/main/res/layout/fragment_contact_parent.xml b/app/src/main/res/layout/fragment_contact_parent.xml index d975818522..b020f444d0 100644 --- a/app/src/main/res/layout/fragment_contact_parent.xml +++ b/app/src/main/res/layout/fragment_contact_parent.xml @@ -6,22 +6,20 @@ android:layout_height="match_parent" tools:context=".contacts.ContactsFragment"> - + - + https:// viasatconnect.com viasatconnect.com + viasatconnect.page.link + chat.veranda.android + open.rocket.chat cloud.rocket.chat/trial https://play.google.com/store/apps/details?id=chat.rocket.android diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 88768162f0..4dd9ead8eb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -363,6 +363,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin Delete My Account Log Out New Group Chat + Share via another App You Can get started by searching for people to chat with or by inviting your friends and family to get the app too. Welcome to Viasat Connect. diff --git a/app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt b/app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt new file mode 100644 index 0000000000..ca039a3e8d --- /dev/null +++ b/app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt @@ -0,0 +1,60 @@ +package chat.rocket.android.dynamiclinks + +import android.content.Context +import android.content.Intent +import android.net.Uri +import chat.rocket.android.util.TimberLogger +import chat.rocket.android.R +import com.google.firebase.dynamiclinks.DynamicLink +import com.google.firebase.dynamiclinks.FirebaseDynamicLinks +import com.google.firebase.dynamiclinks.ShortDynamicLink +import javax.inject.Inject + +// DEBUG +import android.widget.Toast + +class DynamicLinksForFirebase @Inject constructor(private var context: Context) : + DynamicLinks { + + private var deepLink: Uri? = null + private var newDeepLink: String? = null + + override fun getDynamicLink(intent: Intent, deepLinkCallback: (Uri?) -> Unit?) { + + FirebaseDynamicLinks.getInstance() + .getDynamicLink(intent) + .addOnSuccessListener { pendingDynamicLinkData -> + if (pendingDynamicLinkData != null) { + deepLink = pendingDynamicLinkData.link + } + deepLinkCallback(deepLink) + } + .addOnFailureListener { e -> TimberLogger.debug("getDynamicLink:onFailure : $e") } + } + + override fun createDynamicLink(username: String, server: String, deepLinkCallback: (String?) -> Unit? ) { + + FirebaseDynamicLinks.getInstance().createDynamicLink() + .setLink(Uri.parse("$server/direct/$username")) + .setDomainUriPrefix("https://" + context.getString(R.string.widechat_deeplink_host)) + .setAndroidParameters( + DynamicLink.AndroidParameters.Builder(context.getString(R.string.widechat_package_name)).build()) + .setSocialMetaTagParameters( + DynamicLink.SocialMetaTagParameters.Builder() + .setTitle(username) + .setDescription("Chat with $username on " + context.getString(R.string.widechat_server_url)) + .build()) + .buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT) + .addOnSuccessListener { result -> + newDeepLink = result.shortLink.toString() + Toast.makeText(context, newDeepLink, Toast.LENGTH_SHORT).show() + deepLinkCallback(newDeepLink) + + }.addOnFailureListener { + // Error + Toast.makeText(context, "Error dynamic link", Toast.LENGTH_SHORT).show() + } + } +} + + diff --git a/app/src/play/java/chat/rocket/android/helper/SmartLockHelper.kt b/app/src/play/java/chat/rocket/android/helper/SmartLockHelper.kt index 6ca1a19e0b..080de37593 100644 --- a/app/src/play/java/chat/rocket/android/helper/SmartLockHelper.kt +++ b/app/src/play/java/chat/rocket/android/helper/SmartLockHelper.kt @@ -45,7 +45,7 @@ object SmartLockHelper { .addOnCompleteListener { when { it.isSuccessful -> { - credential = it.result.credential + credential = it.result!!.credential } it.exception is ResolvableApiException -> { val resolvableApiException = (it.exception as ResolvableApiException) diff --git a/dependencies.gradle b/dependencies.gradle index c37fe53944..02e713d061 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -22,9 +22,10 @@ ext { workmanager : '1.0.0-alpha09', dagger : '2.16', - firebaseCloudMessage : '17.3.0', - firebaseAnalytics : '16.0.3', - playServices : '16.0.0', + firebaseCloudMessage : '17.3.4', + firebaseAnalytics : '16.0.6', + dynamiclinks : '16.1.5', + playServices : '16.0.1', exoPlayer : '2.8.2', flexbox : '1.1.0', material : '1.0.0-beta01', @@ -55,7 +56,7 @@ ext { // For wearable wear : '2.3.0', - playServicesWearable : '15.0.1', + playServicesWearable : '16.0.1', supportWearable : '27.1.1', // For testing @@ -129,6 +130,7 @@ ext { fcm : "com.google.firebase:firebase-messaging:${versions.firebaseCloudMessage}", firebaseAnalytics : "com.google.firebase:firebase-core:${versions.firebaseAnalytics}", playServicesAuth : "com.google.android.gms:play-services-auth:${versions.playServices}", + dynamiclinks : "com.google.firebase:firebase-dynamic-links:${versions.dynamiclinks}", // For wearable wearable : "com.google.android.support:wearable:${versions.wear}",