Skip to content

Commit

Permalink
Merge branch 'ear_shailesh_dynamicLink' of https://github.com/WideCha…
Browse files Browse the repository at this point in the history
…t/Rocket.Chat.Android into ear_shailesh_dynamicLink
  • Loading branch information
ericrosenthal committed Jan 28, 2019
2 parents 92d3d46 + c088591 commit ced393b
Show file tree
Hide file tree
Showing 19 changed files with 360 additions and 205 deletions.
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import chat.rocket.core.internal.rest.getCustomEmojis
import com.facebook.drawee.backends.pipeline.DraweeConfig
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.google.firebase.FirebaseApp
import com.jakewharton.threetenabp.AndroidThreeTen
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasActivityInjector
Expand Down Expand Up @@ -100,8 +99,6 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje

AndroidThreeTen.init(this)

FirebaseApp.initializeApp(this)

setupFabric(this)
setupFresco()
setupTimber()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package chat.rocket.android.authentication.domain.model

import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import timber.log.Timber

// see https://rocket.chat/docs/developer-guides/deeplink/ for documentation

@SuppressLint("ParcelCreator")
@Parcelize
data class DeepLinkInfo(
val url: String,
val userId: String?,
val token: String?,
val rid: String?,
val roomType: String?,
val roomName: String?
) : Parcelable

fun Uri.getDeepLinkInfo(): DeepLinkInfo? {
return if (isAuthenticationDeepLink()) {
val host = getQueryParameter("host")
val url = if (host.startsWith("http")) host else "https://$host"
val userId = getQueryParameter("userId")
val token = getQueryParameter("token")
try {
DeepLinkInfo(url, userId, token, null, null, null)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing auth deeplink")
null
}
} else if (isCustomSchemeRoomLink()) {
val hostValue = getQueryParameter("host")
val url = if (hostValue.startsWith("http")) hostValue else "https://$hostValue"
val rid = getQueryParameter("rid")
val pathValue = getQueryParameter("path")
val pathSplit = pathValue.split("/")
val roomType = pathSplit[0]
val roomName = pathSplit[1]
try {
DeepLinkInfo(url, null, null, rid, roomType, roomName)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing custom scheme room link")
null
}
} else if (isWebSchemeRoomLink()) {
val url = "https://$host"
val pathSplit = path.split("/")
val roomType = pathSplit[1]
val roomName = pathSplit[2]
try {
DeepLinkInfo(url, null, null, null, roomType, roomName)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing login deeplink")
null
}
} else null
}

fun Intent.isSupportedLink(): Boolean {
return (action == Intent.ACTION_VIEW && data != null &&
(data.isDynamicLink() || data.isAuthenticationDeepLink() ||
data.isCustomSchemeRoomLink() || data.isWebSchemeRoomLink()))
}

fun Uri.isDynamicLink(): Boolean {
return (host != null && host.contains("page.link", ignoreCase = true))
}

// Authentication deep link defined here: https://rocket.chat/docs/developer-guides/deeplink/#authentication
private inline fun Uri.isAuthenticationDeepLink(): Boolean {
if (host == "auth")
return true
else if (host == "go.rocket.chat" && path == "/auth")
return true
return false
}

// Custom scheme room deep link defined here: https://rocket.chat/docs/developer-guides/deeplink/#channel--group--dm
private inline fun Uri.isCustomSchemeRoomLink(): Boolean {
if (scheme.startsWith("rocketchat") &&
host == "room")
return true
return false
}

// http(s) scheme deep link not yet documented. Ex: https://viasatconnect.com/direct/testuser1
private inline fun Uri.isWebSchemeRoomLink(): Boolean {
val roomType = path.split("/")[1]
if (scheme.startsWith("http") &&
(roomType == "channel" || roomType == "group" || roomType == "direct"))
return true
return false
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package chat.rocket.android.authentication.loginoptions.presentation

import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository
Expand Down Expand Up @@ -89,7 +89,7 @@ class LoginOptionsPresenter @Inject constructor(
doAuthentication(TYPE_LOGIN_SAML)
}

fun authenticateWithDeepLink(deepLinkInfo: LoginDeepLinkInfo) {
fun authenticateWithDeepLink(deepLinkInfo: DeepLinkInfo) {
val serverUrl = deepLinkInfo.url
setupConnectionInfo(serverUrl)
if (deepLinkInfo.userId != null && deepLinkInfo.token != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.loginoptions.presentation.LoginOptionsPresenter
import chat.rocket.android.authentication.loginoptions.presentation.LoginOptionsView
import chat.rocket.android.authentication.ui.AuthenticationActivity
Expand Down Expand Up @@ -59,7 +59,6 @@ private const val SAML_SERVICE_BUTTON_COLOR = "saml_service_button_color"
private const val TOTAL_SOCIAL_ACCOUNTS = "total_social_accounts"
private const val IS_LOGIN_FORM_ENABLED = "is_login_form_enabled"
private const val IS_NEW_ACCOUNT_CREATION_ENABLED = "is_new_account_creation_enabled"
private const val DEEP_LINK_INFO = "deep-link-info"

internal const val REQUEST_CODE_FOR_OAUTH = 1
internal const val REQUEST_CODE_FOR_CAS = 2
Expand Down Expand Up @@ -91,7 +90,7 @@ fun newInstance(
totalSocialAccountsEnabled: Int = 0,
isLoginFormEnabled: Boolean,
isNewAccountCreationEnabled: Boolean,
deepLinkInfo: LoginDeepLinkInfo? = null
deepLinkInfo: DeepLinkInfo? = null
): Fragment {
return LoginOptionsFragment().apply {
arguments = Bundle(23).apply {
Expand Down Expand Up @@ -120,7 +119,7 @@ fun newInstance(
putInt(TOTAL_SOCIAL_ACCOUNTS, totalSocialAccountsEnabled)
putBoolean(IS_LOGIN_FORM_ENABLED, isLoginFormEnabled)
putBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED, isNewAccountCreationEnabled)
putParcelable(DEEP_LINK_INFO, deepLinkInfo)
putParcelable(Constants.DEEP_LINK_INFO, deepLinkInfo)
}
}
}
Expand Down Expand Up @@ -155,7 +154,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
private var totalSocialAccountsEnabled = 0
private var isLoginFormEnabled = false
private var isNewAccountCreationEnabled = false
private var deepLinkInfo: LoginDeepLinkInfo? = null
private var deepLinkInfo: DeepLinkInfo? = null

// WIDECHAT - replace the RC login screen with our welcome and login buttons view
private var auth_fragment: Int = R.layout.fragment_authentication_widechat_login_options
Expand Down Expand Up @@ -195,7 +194,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
totalSocialAccountsEnabled = bundle.getInt(TOTAL_SOCIAL_ACCOUNTS)
isLoginFormEnabled = bundle.getBoolean(IS_LOGIN_FORM_ENABLED)
isNewAccountCreationEnabled = bundle.getBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED)
deepLinkInfo = bundle.getParcelable(DEEP_LINK_INFO)
deepLinkInfo = bundle.getParcelable(Constants.DEEP_LINK_INFO)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,30 @@ package chat.rocket.android.authentication.presentation
import android.content.Intent
import chat.rocket.android.R
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.helper.Constants
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.android.util.extensions.addFragmentBackStack
import chat.rocket.android.util.extensions.toPreviousView
import chat.rocket.android.webview.ui.webViewIntent
import chat.rocket.common.util.ifNull

class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
public var savedDeepLinkInfo: DeepLinkInfo? = null

fun toSignInToYourServer() {
fun saveDeepLinkInfo(deepLinkInfo: DeepLinkInfo) {
savedDeepLinkInfo = deepLinkInfo
}
fun toOnBoarding() {
activity.addFragmentBackStack(ScreenViewEvent.OnBoarding.screenName, R.id.fragment_container) {
chat.rocket.android.authentication.onboarding.ui.newInstance()
}
}
fun toSignInToYourServer(deepLinkInfo: DeepLinkInfo? = null) {
activity.addFragmentBackStack(ScreenViewEvent.Server.screenName, R.id.fragment_container) {
chat.rocket.android.authentication.server.ui.newInstance()
chat.rocket.android.authentication.server.ui.newInstance(deepLinkInfo)
}
}

Expand Down Expand Up @@ -45,7 +56,7 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
totalSocialAccountsEnabled: Int = 0,
isLoginFormEnabled: Boolean = true,
isNewAccountCreationEnabled: Boolean = true,
deepLinkInfo: LoginDeepLinkInfo? = null
deepLinkInfo: DeepLinkInfo? = null
) {
activity.addFragmentBackStack(
ScreenViewEvent.LoginOptions.screenName,
Expand Down Expand Up @@ -127,13 +138,23 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}

fun toChatList() {
activity.startActivity(Intent(activity, MainActivity::class.java))
fun toChatList(serverUrl: String) {
activity.startActivity(activity.changeServerIntent(serverUrl))
activity.finish()
}

fun toChatList(serverUrl: String) {
activity.startActivity(activity.changeServerIntent(serverUrl))
fun toChatList(passedDeepLinkInfo: DeepLinkInfo? = null) {
val deepLinkInfo = if (passedDeepLinkInfo != null) passedDeepLinkInfo else savedDeepLinkInfo
savedDeepLinkInfo = null

if (deepLinkInfo != null) {
activity.startActivity(Intent(activity, MainActivity::class.java).also {
it.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
it.putExtra(Constants.DEEP_LINK_INFO, deepLinkInfo)
})
} else {
activity.startActivity(Intent(activity, MainActivity::class.java))
}
activity.finish()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package chat.rocket.android.authentication.presentation

import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetAccountInteractor
Expand Down Expand Up @@ -52,5 +53,9 @@ class AuthenticationPresenter @Inject constructor(
fun privacyPolicy(toolbarTitle: String) =
serverInteractor.get()?.let { navigator.toWebPage(it.privacyPolicyUrl(), toolbarTitle) }

fun saveDeepLinkInfo(deepLinkInfo: DeepLinkInfo) = navigator.saveDeepLinkInfo(deepLinkInfo)
fun toOnBoarding() = navigator.toOnBoarding()
fun toSignInToYourServer(deepLinkInfo: DeepLinkInfo? = null) = navigator.toSignInToYourServer(deepLinkInfo)
fun toChatList() = navigator.toChatList()
fun toChatList(deepLinkInfo: DeepLinkInfo) = navigator.toChatList(deepLinkInfo)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package chat.rocket.android.authentication.server.presentation

import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy
Expand Down Expand Up @@ -79,7 +79,7 @@ class ServerPresenter @Inject constructor(
}
}

fun deepLink(deepLinkInfo: LoginDeepLinkInfo) {
fun deepLink(deepLinkInfo: DeepLinkInfo) {
connectToServer(deepLinkInfo.url) {
navigator.toLoginOptions(deepLinkInfo.url, deepLinkInfo = deepLinkInfo)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import chat.rocket.android.BuildConfig
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.helper.Constants
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.hintContent
Expand All @@ -42,16 +43,20 @@ import kotlinx.android.synthetic.main.fragment_authentication_server.*
import okhttp3.HttpUrl
import javax.inject.Inject

fun newInstance() = ServerFragment()

private const val DEEP_LINK_INFO = "DeepLinkInfo"
fun newInstance(deepLinkInfo: DeepLinkInfo?): ServerFragment {
val fragment = ServerFragment()
val args = Bundle()
args.putParcelable(Constants.DEEP_LINK_INFO, deepLinkInfo)
fragment.setArguments(args)
return fragment
}

class ServerFragment : Fragment(), ServerView {
@Inject
lateinit var presenter: ServerPresenter
@Inject
lateinit var analyticsManager: AnalyticsManager
private var deepLinkInfo: LoginDeepLinkInfo? = null
private var deepLinkInfo: DeepLinkInfo? = null
private var protocol = "https://"
private var isDomainAppended = false
private var appendedText = ""
Expand All @@ -66,7 +71,7 @@ class ServerFragment : Fragment(), ServerView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
deepLinkInfo = arguments?.getParcelable(DEEP_LINK_INFO)
deepLinkInfo = arguments?.getParcelable(Constants.DEEP_LINK_INFO)
}

override fun onCreateView(
Expand Down
Loading

0 comments on commit ced393b

Please sign in to comment.