Permalink: start handling permalink from outside the app

This commit is contained in:
ganfra 2019-11-21 19:15:58 +01:00 committed by Benoit Marty
parent cfee6a43fd
commit 91c98d4bfb
7 changed files with 138 additions and 38 deletions

View file

@ -65,7 +65,13 @@
<activity android:name=".features.roomdirectory.RoomDirectoryActivity" /> <activity android:name=".features.roomdirectory.RoomDirectoryActivity" />
<activity android:name=".features.roomdirectory.roompreview.RoomPreviewActivity" /> <activity android:name=".features.roomdirectory.roompreview.RoomPreviewActivity" />
<activity android:name=".features.home.room.filtered.FilteredRoomsActivity" /> <activity android:name=".features.home.room.filtered.FilteredRoomsActivity" />
<activity android:name=".features.home.room.detail.RoomDetailActivity" /> <activity
android:name=".features.home.room.detail.RoomDetailActivity"
android:parentActivityName=".features.home.HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".features.home.HomeActivity" />
</activity>
<activity android:name=".features.debug.DebugMenuActivity" /> <activity android:name=".features.debug.DebugMenuActivity" />
<activity android:name=".features.home.createdirect.CreateDirectRoomActivity" /> <activity android:name=".features.home.createdirect.CreateDirectRoomActivity" />
<activity android:name=".features.webview.VectorWebViewActivity" /> <activity android:name=".features.webview.VectorWebViewActivity" />
@ -102,6 +108,18 @@
<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">
<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" />
</intent-filter>
</activity>
<!-- Services --> <!-- Services -->
<service <service

View file

@ -41,6 +41,7 @@ import im.vector.riotx.features.login.LoginActivity
import im.vector.riotx.features.media.ImageMediaViewerActivity import im.vector.riotx.features.media.ImageMediaViewerActivity
import im.vector.riotx.features.media.VideoMediaViewerActivity import im.vector.riotx.features.media.VideoMediaViewerActivity
import im.vector.riotx.features.navigation.Navigator import im.vector.riotx.features.navigation.Navigator
import im.vector.riotx.features.permalink.PermalinkHandlerActivity
import im.vector.riotx.features.rageshake.BugReportActivity import im.vector.riotx.features.rageshake.BugReportActivity
import im.vector.riotx.features.rageshake.BugReporter import im.vector.riotx.features.rageshake.BugReporter
import im.vector.riotx.features.rageshake.RageShake import im.vector.riotx.features.rageshake.RageShake
@ -132,6 +133,8 @@ interface ScreenComponent {
fun inject(activity: SoftLogoutActivity) fun inject(activity: SoftLogoutActivity)
fun inject(permalinkHandlerActivity: PermalinkHandlerActivity)
@Component.Factory @Component.Factory
interface Factory { interface Factory {
fun create(vectorComponent: VectorComponent, fun create(vectorComponent: VectorComponent,

View file

@ -86,8 +86,8 @@ import im.vector.riotx.features.autocomplete.command.CommandAutocompletePolicy
import im.vector.riotx.features.autocomplete.user.AutocompleteUserPresenter import im.vector.riotx.features.autocomplete.user.AutocompleteUserPresenter
import im.vector.riotx.features.command.Command import im.vector.riotx.features.command.Command
import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.NavigateToRoomInterceptor import im.vector.riotx.features.permalink.NavigateToRoomInterceptor
import im.vector.riotx.features.home.PermalinkHandler import im.vector.riotx.features.permalink.PermalinkHandler
import im.vector.riotx.features.home.getColorFromUserId import im.vector.riotx.features.home.getColorFromUserId
import im.vector.riotx.features.home.room.detail.composer.TextComposerAction import im.vector.riotx.features.home.room.detail.composer.TextComposerAction
import im.vector.riotx.features.home.room.detail.composer.TextComposerView import im.vector.riotx.features.home.room.detail.composer.TextComposerView

View file

@ -38,14 +38,39 @@ import im.vector.riotx.features.share.SharedData
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import androidx.core.app.TaskStackBuilder
@Singleton @Singleton
class DefaultNavigator @Inject constructor() : Navigator { class DefaultNavigator @Inject constructor() : Navigator {
override fun openRoom(context: Context, roomId: String, eventId: String?) { override fun openRoom(context: Context, roomId: String, eventId: String?, buildTask: Boolean) {
val args = RoomDetailArgs(roomId, eventId) val args = RoomDetailArgs(roomId, eventId)
val intent = RoomDetailActivity.newIntent(context, args) val intent = RoomDetailActivity.newIntent(context, args)
context.startActivity(intent) if (buildTask) {
val stackBuilder = TaskStackBuilder.create(context)
stackBuilder.addNextIntentWithParentStack(intent)
stackBuilder.startActivities()
} else {
context.startActivity(intent)
}
}
override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String, eventId: String?, buildTask: Boolean) {
if (context is VectorBaseActivity) {
context.notImplemented("Open not joined room")
} else {
context.toast(R.string.not_implemented)
}
}
override fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean) {
Timber.v("Open group detail $groupId")
}
override fun openUserDetail(userId: String, context: Context, buildTask: Boolean) {
Timber.v("Open user detail $userId")
} }
override fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData) { override fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData) {
@ -55,14 +80,6 @@ class DefaultNavigator @Inject constructor() : Navigator {
activity.finish() activity.finish()
} }
override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String, eventId: String?) {
if (context is VectorBaseActivity) {
context.notImplemented("Open not joined room")
} else {
context.toast(R.string.not_implemented)
}
}
override fun openRoomPreview(publicRoom: PublicRoom, context: Context) { override fun openRoomPreview(publicRoom: PublicRoom, context: Context) {
val intent = RoomPreviewActivity.getIntent(context, publicRoom) val intent = RoomPreviewActivity.getIntent(context, publicRoom)
context.startActivity(intent) context.startActivity(intent)
@ -105,14 +122,6 @@ class DefaultNavigator @Inject constructor() : Navigator {
context.startActivity(KeysBackupManageActivity.intent(context)) context.startActivity(KeysBackupManageActivity.intent(context))
} }
override fun openGroupDetail(groupId: String, context: Context) {
Timber.v("Open group detail $groupId")
}
override fun openUserDetail(userId: String, context: Context) {
Timber.v("Open user detail $userId")
}
override fun openRoomSettings(context: Context, roomId: String) { override fun openRoomSettings(context: Context, roomId: String) {
Timber.v("Open room settings$roomId") Timber.v("Open room settings$roomId")
} }

View file

@ -23,11 +23,11 @@ import im.vector.riotx.features.share.SharedData
interface Navigator { interface Navigator {
fun openRoom(context: Context, roomId: String, eventId: String? = null) fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false)
fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData) fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData)
fun openNotJoinedRoom(context: Context, roomIdOrAlias: String, eventId: String? = null) fun openNotJoinedRoom(context: Context, roomIdOrAlias: String, eventId: String? = null, buildTask: Boolean = false)
fun openRoomPreview(publicRoom: PublicRoom, context: Context) fun openRoomPreview(publicRoom: PublicRoom, context: Context)
@ -47,9 +47,9 @@ interface Navigator {
fun openKeysBackupManager(context: Context) fun openKeysBackupManager(context: Context)
fun openGroupDetail(groupId: String, context: Context) fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean = false)
fun openUserDetail(userId: String, context: Context) fun openUserDetail(userId: String, context: Context, buildTask: Boolean = false)
fun openRoomSettings(context: Context, roomId: String) fun openRoomSettings(context: Context, roomId: String)
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.riotx.features.home package im.vector.riotx.features.permalink
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
@ -27,12 +27,22 @@ import javax.inject.Inject
class PermalinkHandler @Inject constructor(private val session: Session, class PermalinkHandler @Inject constructor(private val session: Session,
private val navigator: Navigator) { private val navigator: Navigator) {
fun launch(context: Context, deepLink: String?, navigateToRoomInterceptor: NavigateToRoomInterceptor? = null): Boolean { fun launch(
context: Context,
deepLink: String?,
navigateToRoomInterceptor: NavigateToRoomInterceptor? = null,
buildTask: Boolean = false
): Boolean {
val uri = deepLink?.let { Uri.parse(it) } val uri = deepLink?.let { Uri.parse(it) }
return launch(context, uri, navigateToRoomInterceptor) return launch(context, uri, navigateToRoomInterceptor, buildTask)
} }
fun launch(context: Context, deepLink: Uri?, navigateToRoomInterceptor: NavigateToRoomInterceptor? = null): Boolean { fun launch(
context: Context,
deepLink: Uri?,
navigateToRoomInterceptor: NavigateToRoomInterceptor? = null,
buildTask: Boolean = false
): Boolean {
if (deepLink == null) { if (deepLink == null) {
return false return false
} }
@ -40,24 +50,23 @@ class PermalinkHandler @Inject constructor(private val session: Session,
return when (val permalinkData = PermalinkParser.parse(deepLink)) { return when (val permalinkData = PermalinkParser.parse(deepLink)) {
is PermalinkData.EventLink -> { is PermalinkData.EventLink -> {
if (navigateToRoomInterceptor?.navToRoom(permalinkData.roomIdOrAlias, permalinkData.eventId) != true) { if (navigateToRoomInterceptor?.navToRoom(permalinkData.roomIdOrAlias, permalinkData.eventId) != true) {
openRoom(context, permalinkData.roomIdOrAlias, permalinkData.eventId) openRoom(context, permalinkData.roomIdOrAlias, permalinkData.eventId, buildTask)
} }
true true
} }
is PermalinkData.RoomLink -> { is PermalinkData.RoomLink -> {
if (navigateToRoomInterceptor?.navToRoom(permalinkData.roomIdOrAlias) != true) { if (navigateToRoomInterceptor?.navToRoom(permalinkData.roomIdOrAlias) != true) {
openRoom(context, permalinkData.roomIdOrAlias) openRoom(context, permalinkData.roomIdOrAlias, null, buildTask)
} }
true true
} }
is PermalinkData.GroupLink -> { is PermalinkData.GroupLink -> {
navigator.openGroupDetail(permalinkData.groupId, context) navigator.openGroupDetail(permalinkData.groupId, context, buildTask)
true false
} }
is PermalinkData.UserLink -> { is PermalinkData.UserLink -> {
navigator.openUserDetail(permalinkData.userId, context) navigator.openUserDetail(permalinkData.userId, context, buildTask)
true true
} }
is PermalinkData.FallbackLink -> { is PermalinkData.FallbackLink -> {
@ -69,11 +78,11 @@ class PermalinkHandler @Inject constructor(private val session: Session,
/** /**
* Open room either joined, or not unknown * Open room either joined, or not unknown
*/ */
private fun openRoom(context: Context, roomIdOrAlias: String, eventId: String? = null) { private fun openRoom(context: Context, roomIdOrAlias: String, eventId: String? = null, buildTask: Boolean) {
if (session.getRoom(roomIdOrAlias) != null) { if (session.getRoom(roomIdOrAlias) != null) {
navigator.openRoom(context, roomIdOrAlias, eventId) navigator.openRoom(context, roomIdOrAlias, eventId, buildTask)
} else { } else {
navigator.openNotJoinedRoom(context, roomIdOrAlias, eventId) navigator.openNotJoinedRoom(context, roomIdOrAlias, eventId, buildTask)
} }
} }
} }

View file

@ -0,0 +1,61 @@
/*
* 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.riotx.features.permalink
import android.content.Intent
import android.os.Bundle
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.di.ScreenComponent
import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.features.login.LoginActivity
import timber.log.Timber
import javax.inject.Inject
class PermalinkHandlerActivity : VectorBaseActivity() {
@Inject lateinit var permalinkHandler: PermalinkHandler
@Inject lateinit var sessionHolder: ActiveSessionHolder
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// If we are not logged in, stop the sharing process and open login screen.
// In the future, we might want to relaunch the sharing process after login.
if (!sessionHolder.hasActiveSession()) {
startLoginActivity()
return
}
val uri = intent.dataString
val isHandled = permalinkHandler.launch(this, uri, buildTask = true)
if (!isHandled) {
Timber.v("Couldn't handle permalink")
}
finish()
}
private fun startLoginActivity() {
val intent = LoginActivity.newIntent(this, null)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
}
}