Permalink: Merge LinkHandlerActivity with PermalinkHandlerActivity

Also convert links to matrix.to before permalink parsing
This commit is contained in:
Florian Renaud 2021-09-16 15:11:46 +02:00
parent 21d0a28150
commit e37fb313c0
9 changed files with 165 additions and 200 deletions

1
changelog.d/4027.feature Normal file
View file

@ -0,0 +1 @@
Add client base url config to customize permalinks

View file

@ -0,0 +1,55 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.android.sdk.api.session.permalinks
import android.net.Uri
/**
* Mapping of an input URI to a matrix.to compliant URI.
*/
object MatrixToMapper {
/**
* Try to convert a URL from an element web instance or from a client permalink to a matrix.to url.
* To be successfully converted, URL path should contain one of the [SUPPORTED_PATHS].
* Examples:
* - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
* - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
* - https://www.example.org/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
*/
fun map(uri: Uri): Uri? {
val uriString = uri.toString()
return when {
// URL is already a matrix.to
uriString.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> uri
// Web or client url
SUPPORTED_PATHS.any { it in uriString } -> {
val path = SUPPORTED_PATHS.first { it in uriString }
Uri.parse(PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path))
}
// URL is not supported
else -> null
}
}
private val SUPPORTED_PATHS = listOf(
"/#/room/",
"/#/user/",
"/#/group/"
)
}

View file

@ -26,6 +26,7 @@ import java.net.URLDecoder
* This class turns a uri to a [PermalinkData] * This class turns a uri to a [PermalinkData]
* element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks * element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks
* or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org) * or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org)
* or client permalinks (e.g. https://www.example.com/#/user/@chagai95:matrix.org)
*/ */
object PermalinkParser { object PermalinkParser {
@ -42,12 +43,14 @@ object PermalinkParser {
* https://github.com/matrix-org/matrix-doc/blob/master/proposals/1704-matrix.to-permalinks.md * https://github.com/matrix-org/matrix-doc/blob/master/proposals/1704-matrix.to-permalinks.md
*/ */
fun parse(uri: Uri): PermalinkData { fun parse(uri: Uri): PermalinkData {
if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { // the client or element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the
return PermalinkData.FallbackLink(uri) // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid
} // so convert URI to matrix.to to simplify parsing process
val matrixToUri = MatrixToMapper.map(uri) ?: return PermalinkData.FallbackLink(uri)
// We can't use uri.fragment as it is decoding to early and it will break the parsing // We can't use uri.fragment as it is decoding to early and it will break the parsing
// of parameters that represents url (like signurl) // of parameters that represents url (like signurl)
val fragment = uri.toString().substringAfter("#") // uri.fragment val fragment = matrixToUri.toString().substringAfter("#") // uri.fragment
if (fragment.isNullOrEmpty()) { if (fragment.isNullOrEmpty()) {
return PermalinkData.FallbackLink(uri) return PermalinkData.FallbackLink(uri)
} }
@ -61,20 +64,14 @@ object PermalinkParser {
.map { URLDecoder.decode(it, "UTF-8") } .map { URLDecoder.decode(it, "UTF-8") }
.take(2) .take(2)
// the element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the val identifier = params.getOrNull(0)
// mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid
var identifier = params.getOrNull(0)
if (identifier.equals("user")) {
identifier = params.getOrNull(1)
}
val extraParameter = params.getOrNull(1) val extraParameter = params.getOrNull(1)
return when { return when {
identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri) identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri)
MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier) MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier)
MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier) MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier)
MatrixPatterns.isRoomId(identifier) -> { MatrixPatterns.isRoomId(identifier) -> {
handleRoomIdCase(fragment, identifier, uri, extraParameter, viaQueryParameters) handleRoomIdCase(fragment, identifier, matrixToUri, extraParameter, viaQueryParameters)
} }
MatrixPatterns.isRoomAlias(identifier) -> { MatrixPatterns.isRoomAlias(identifier) -> {
PermalinkData.RoomLink( PermalinkData.RoomLink(

View file

@ -180,7 +180,9 @@
<activity android:name=".features.createdirect.CreateDirectRoomActivity" /> <activity android:name=".features.createdirect.CreateDirectRoomActivity" />
<activity android:name=".features.invite.InviteUsersToRoomActivity" /> <activity android:name=".features.invite.InviteUsersToRoomActivity" />
<activity android:name=".features.webview.VectorWebViewActivity" /> <activity android:name=".features.webview.VectorWebViewActivity" />
<activity android:name=".features.link.LinkHandlerActivity"> <activity
android:name=".features.link.LinkHandlerActivity"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
@ -196,6 +198,30 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity-alias
android:name=".features.permalink.PermalinkHandlerActivity"
android:exported="true"
android:launchMode="singleTask"
android:targetActivity=".features.link.LinkHandlerActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="matrix.to" />
<data
android:host="user"
android:scheme="element" />
<data
android:host="room"
android:scheme="element" />
</intent-filter>
</activity-alias>
<activity <activity
android:name=".features.share.IncomingShareActivity" android:name=".features.share.IncomingShareActivity"
android:parentActivityName=".features.home.HomeActivity"> android:parentActivityName=".features.home.HomeActivity">
@ -230,27 +256,6 @@
<activity <activity
android:name=".features.signout.soft.SoftLogoutActivity" android:name=".features.signout.soft.SoftLogoutActivity"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity
android:name=".features.permalink.PermalinkHandlerActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="matrix.to" />
<data
android:host="user"
android:scheme="element" />
<data
android:host="room"
android:scheme="element" />
</intent-filter>
</activity>
<activity <activity
android:name=".features.roommemberprofile.RoomMemberProfileActivity" android:name=".features.roommemberprofile.RoomMemberProfileActivity"
@ -271,12 +276,12 @@
android:name=".features.attachments.preview.AttachmentsPreviewActivity" android:name=".features.attachments.preview.AttachmentsPreviewActivity"
android:theme="@style/Theme.Vector.Black.AttachmentsPreview" /> android:theme="@style/Theme.Vector.Black.AttachmentsPreview" />
<activity <activity
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:name=".features.call.VectorCallActivity" android:name=".features.call.VectorCallActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:excludeFromRecents="true"
android:launchMode="singleTask" android:launchMode="singleTask"
android:taskAffinity=".features.call.VectorCallActivity" android:supportsPictureInPicture="true"
android:excludeFromRecents="true" /> android:taskAffinity=".features.call.VectorCallActivity" />
<!-- PIP Support https://developer.android.com/guide/topics/ui/picture-in-picture --> <!-- PIP Support https://developer.android.com/guide/topics/ui/picture-in-picture -->
<activity <activity
android:name=".features.call.conference.VectorJitsiActivity" android:name=".features.call.conference.VectorJitsiActivity"

View file

@ -62,7 +62,6 @@ import im.vector.app.features.matrixto.MatrixToBottomSheet
import im.vector.app.features.media.BigImageViewerActivity import im.vector.app.features.media.BigImageViewerActivity
import im.vector.app.features.media.VectorAttachmentViewerActivity import im.vector.app.features.media.VectorAttachmentViewerActivity
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.permalink.PermalinkHandlerActivity
import im.vector.app.features.pin.PinLocker import im.vector.app.features.pin.PinLocker
import im.vector.app.features.qrcode.QrCodeScannerActivity import im.vector.app.features.qrcode.QrCodeScannerActivity
import im.vector.app.features.rageshake.BugReportActivity import im.vector.app.features.rageshake.BugReportActivity
@ -153,7 +152,6 @@ interface ScreenComponent {
fun inject(activity: CreateDirectRoomActivity) fun inject(activity: CreateDirectRoomActivity)
fun inject(activity: IncomingShareActivity) fun inject(activity: IncomingShareActivity)
fun inject(activity: SoftLogoutActivity) fun inject(activity: SoftLogoutActivity)
fun inject(activity: PermalinkHandlerActivity)
fun inject(activity: QrCodeScannerActivity) fun inject(activity: QrCodeScannerActivity)
fun inject(activity: DebugMenuActivity) fun inject(activity: DebugMenuActivity)
fun inject(activity: SharedSecureStorageActivity) fun inject(activity: SharedSecureStorageActivity)

View file

@ -51,6 +51,9 @@ import im.vector.app.features.navigation.Navigator
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.NavigationInterceptor
import im.vector.app.features.permalink.PermalinkHandler import im.vector.app.features.permalink.PermalinkHandler
import im.vector.app.features.permalink.PermalinkHandler.Companion.MATRIX_TO_CUSTOM_SCHEME_URL_BASE
import im.vector.app.features.permalink.PermalinkHandler.Companion.ROOM_LINK_PREFIX
import im.vector.app.features.permalink.PermalinkHandler.Companion.USER_LINK_PREFIX
import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.DefaultVectorAlert
import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.popup.VerificationVectorAlert import im.vector.app.features.popup.VerificationVectorAlert
@ -266,20 +269,19 @@ class HomeActivity :
private fun handleIntent(intent: Intent?) { private fun handleIntent(intent: Intent?) {
intent?.dataString?.let { deepLink -> intent?.dataString?.let { deepLink ->
val resolvedLink = when { val resolvedLink = when {
deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink // Element custom scheme is not handled by the sdk, convert it to matrix.to link for compatibility
deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> {
// This is a bit ugly, but for now just convert to matrix.to link for compatibility val let = when {
when {
deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length)
deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length) deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length)
else -> null else -> null
}?.let { }?.let { permalinkId ->
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId)
} }
let
} }
else -> return@let else -> deepLink
} }
permalinkHandler.launch( permalinkHandler.launch(
context = this, context = this,
deepLink = resolvedLink, deepLink = resolvedLink,
@ -290,9 +292,11 @@ class HomeActivity :
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe { isHandled -> .subscribe { isHandled ->
if (!isHandled) { if (!isHandled) {
val isMatrixToLink = deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE)
|| deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE)
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle(R.string.dialog_title_error) .setTitle(R.string.dialog_title_error)
.setMessage(R.string.permalink_malformed) .setMessage(if (isMatrixToLink) R.string.permalink_malformed else R.string.universal_link_malformed)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.show() .show()
} }
@ -559,10 +563,6 @@ class HomeActivity :
putExtra(MvRx.KEY_ARG, args) putExtra(MvRx.KEY_ARG, args)
} }
} }
private const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://"
private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/"
private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/"
} }
override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState) override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState)

View file

@ -27,13 +27,12 @@ import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.databinding.ActivityProgressBinding import im.vector.app.databinding.ActivityProgressBinding
import im.vector.app.features.home.HomeActivity
import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginConfig
import im.vector.app.features.permalink.PermalinkHandler import im.vector.app.features.permalink.PermalinkHandler
import io.reactivex.android.schedulers.AndroidSchedulers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -45,32 +44,40 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
@Inject lateinit var errorFormatter: ErrorFormatter @Inject lateinit var errorFormatter: ErrorFormatter
@Inject lateinit var permalinkHandler: PermalinkHandler @Inject lateinit var permalinkHandler: PermalinkHandler
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
override fun injectWith(injector: ScreenComponent) { override fun injectWith(injector: ScreenComponent) {
injector.inject(this) injector.inject(this)
} }
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
override fun initUiAndData() { override fun initUiAndData() {
val uri = intent.data handleIntent()
}
if (uri == null) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
handleIntent()
}
private fun handleIntent() {
val uri = intent.data
when {
uri == null -> {
// Should not happen // Should not happen
Timber.w("Uri is null") Timber.w("Uri is null")
finish() finish()
return
} }
uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null -> handleConfigUrl(uri)
if (uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null) { uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> handleSupportedHostUrl()
handleConfigUrl(uri) uri.toString().startsWith(PermalinkHandler.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> handleSupportedHostUrl()
} else if (resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host)) { resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host) -> handleSupportedHostUrl()
handleSupportedHostUrl(uri) else -> {
} else {
// Other links are not yet handled, but should not come here (manifest configuration error?) // Other links are not yet handled, but should not come here (manifest configuration error?)
toast(R.string.universal_link_malformed) toast(R.string.universal_link_malformed)
finish() finish()
} }
} }
}
private fun handleConfigUrl(uri: Uri) { private fun handleConfigUrl(uri: Uri) {
if (sessionHolder.hasActiveSession()) { if (sessionHolder.hasActiveSession()) {
@ -81,53 +88,28 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
} }
} }
private fun handleSupportedHostUrl(uri: Uri) { private fun handleSupportedHostUrl() {
// If we are not logged in, open login screen.
// In the future, we might want to relaunch the process after login.
if (!sessionHolder.hasActiveSession()) { if (!sessionHolder.hasActiveSession()) {
startLoginActivity(uri) startLoginActivity()
finish() return
} else {
convertUriToPermalink(uri)?.let { permalink ->
startPermalinkHandler(permalink)
} ?: run {
// Host is correct but we do not recognize path
Timber.w("Unable to handle this uri: $uri")
finish()
}
} }
// We forward intent to HomeActivity (singleTask) to avoid the dueling app problem
// https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances
intent.setClass(this, HomeActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(intent)
} }
/** /**
* Convert a URL of element web instance to a matrix.to url * Start the login screen with identity server and homeserver pre-filled, if any
* Examples:
* - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
* - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
*/ */
private fun convertUriToPermalink(uri: Uri): String? { private fun startLoginActivity(uri: Uri? = null) {
val uriString = uri.toString()
val path = SUPPORTED_PATHS.find { it in uriString } ?: return null
return PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path)
}
private fun startPermalinkHandler(permalink: String) {
permalinkHandler.launch(this, permalink, buildTask = true)
.delay(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { isHandled ->
if (!isHandled) {
toast(R.string.universal_link_malformed)
}
finish()
}
.disposeOnDestroy()
}
/**
* Start the login screen with identity server and homeserver pre-filled
*/
private fun startLoginActivity(uri: Uri) {
navigator.openLogin( navigator.openLogin(
context = this, context = this,
loginConfig = LoginConfig.parse(uri), loginConfig = uri?.let { LoginConfig.parse(uri) },
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
) )
finish() finish()
@ -173,12 +155,4 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
.setPositiveButton(R.string.ok) { _, _ -> finish() } .setPositiveButton(R.string.ok) { _, _ -> finish() }
.show() .show()
} }
companion object {
private val SUPPORTED_PATHS = listOf(
"/#/room/",
"/#/user/",
"/#/group/"
)
}
} }

View file

@ -29,6 +29,7 @@ import io.reactivex.schedulers.Schedulers
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkData
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.Optional
@ -55,7 +56,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
navigationInterceptor: NavigationInterceptor? = null, navigationInterceptor: NavigationInterceptor? = null,
buildTask: Boolean = false buildTask: Boolean = false
): Single<Boolean> { ): Single<Boolean> {
if (deepLink == null) { if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) {
return Single.just(false) return Single.just(false)
} }
return Single return Single
@ -122,6 +123,13 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
} }
} }
private fun isPermalinkSupported(context: Context, url: String): Boolean {
return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE)
|| context.resources.getStringArray(R.array.permalink_supported_hosts).any {
url.startsWith(it)
}
}
private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> { private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> {
val session = activeSessionHolder.getSafeActiveSession() val session = activeSessionHolder.getSafeActiveSession()
return if (isRoomAlias && session != null) { return if (isRoomAlias && session != null) {
@ -179,6 +187,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
} }
} }
} }
companion object {
const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://"
const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/"
const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/"
}
} }
interface NavigationInterceptor { interface NavigationInterceptor {

View file

@ -1,79 +0,0 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.permalink
import android.content.Intent
import android.os.Bundle
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.FragmentProgressBinding
import im.vector.app.features.home.HomeActivity
import im.vector.app.features.home.LoadingFragment
import javax.inject.Inject
class PermalinkHandlerActivity : VectorBaseActivity<FragmentProgressBinding>() {
@Inject lateinit var permalinkHandler: PermalinkHandler
@Inject lateinit var sessionHolder: ActiveSessionHolder
override fun getBinding() = FragmentProgressBinding.inflate(layoutInflater)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_simple)
if (isFirstCreation()) {
replaceFragment(R.id.simpleFragmentContainer, LoadingFragment::class.java)
}
handleIntent()
}
private fun handleIntent() {
// If we are not logged in, open login screen.
// In the future, we might want to relaunch the process after login.
if (!sessionHolder.hasActiveSession()) {
startLoginActivity()
return
}
// We forward intent to HomeActivity (singleTask) to avoid the dueling app problem
// https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances
intent.setClass(this, HomeActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(intent)
finish()
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
handleIntent()
}
private fun startLoginActivity() {
navigator.openLogin(
context = this,
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
)
finish()
}
}