Skip to content

Commit

Permalink
use clipboard hack to get deferred deeplink
Browse files Browse the repository at this point in the history
  • Loading branch information
NIkita Fedrunov committed Dec 23, 2022
1 parent 67edf66 commit 2dc103f
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.identity.IdentityService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.DeferredPermalinkService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.presence.PresenceService
import org.matrix.android.sdk.api.session.profile.ProfileService
Expand Down Expand Up @@ -248,6 +249,11 @@ interface Session {
*/
fun permalinkService(): PermalinkService

/**
* Returns the deferredPermalinkService service associated with the session.
*/
fun deferredPermalinkService(): DeferredPermalinkService

/**
* Returns the search service associated with the session.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2022 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

/**
* Service to handle deferred links, e.g. when user open link to the room but the app is not installed yet
*/
interface DeferredPermalinkService {

/**
* Checks system clipboard for matrix.to links and returns first room link if any found
* @return first room link in clipboard or null if none is found
*/
fun getLinkFromClipBoard(): String?
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import org.matrix.android.sdk.api.session.identity.IdentityService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.DeferredPermalinkService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.presence.PresenceService
import org.matrix.android.sdk.api.session.profile.ProfileService
Expand Down Expand Up @@ -135,6 +136,7 @@ internal class DefaultSession @Inject constructor(
@UnauthenticatedWithCertificate
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>,
private val sessionState: SessionState,
private val deferredPermalinkService: Lazy<DeferredPermalinkService>,
) : Session,
GlobalErrorHandler.Listener {

Expand Down Expand Up @@ -222,6 +224,8 @@ internal class DefaultSession @Inject constructor(
override fun eventStreamService(): EventStreamService = eventStreamService.get()
override fun fileService(): FileService = defaultFileService.get()
override fun permalinkService(): PermalinkService = permalinkService.get()
override fun deferredPermalinkService(): DeferredPermalinkService = deferredPermalinkService.get()

override fun widgetService(): WidgetService = widgetService.get()
override fun mediaService(): MediaService = mediaService.get()
override fun integrationManagerService(): IntegrationManagerService = integrationManagerService.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService
import org.matrix.android.sdk.api.session.events.EventService
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.DeferredPermalinkService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
Expand Down Expand Up @@ -83,6 +84,7 @@ import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapab
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService
import org.matrix.android.sdk.internal.session.permalinks.DefaultDeferredPermalinkService
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor
import org.matrix.android.sdk.internal.session.room.aggregation.poll.DefaultPollAggregationProcessor
Expand Down Expand Up @@ -405,4 +407,7 @@ internal abstract class SessionModule {

@Binds
abstract fun bindPollAggregationProcessor(processor: DefaultPollAggregationProcessor): PollAggregationProcessor

@Binds
abstract fun bindDeferredPermalinkService(service: DefaultDeferredPermalinkService): DeferredPermalinkService
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2022 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.internal.session.permalinks

import android.content.ClipboardManager
import android.content.Context
import org.matrix.android.sdk.api.session.permalinks.DeferredPermalinkService
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
import androidx.core.content.getSystemService
import javax.inject.Inject

class DefaultDeferredPermalinkService @Inject constructor(
private val context: Context
) : DeferredPermalinkService {

override fun getLinkFromClipBoard(): String? {
val clipboard = context.getSystemService<ClipboardManager>()
clipboard?.primaryClip?.let { clip ->
if (clip.itemCount == 0) {
return null
}
for (i in 0 until clip.itemCount) {
val clipText = clip.getItemAt(i).text.toString()
val data = PermalinkParser.parse(clipText)
if (data is PermalinkData.RoomLink) {
return clipText
}
}
}
return null
}
}
12 changes: 12 additions & 0 deletions vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ class HomeActivity :
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
is HomeActivityViewEvents.AskUserForPushDistributor -> askUserToSelectPushDistributor()
is HomeActivityViewEvents.NavigatePermalink -> handleNavigatePermalink(it.permalink)
}
}
homeActivityViewModel.onEach { renderState(it) }
Expand All @@ -279,6 +280,17 @@ class HomeActivity :
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
}

private fun handleNavigatePermalink(permalink: String) {
lifecycleScope.launch {
permalinkHandler.launch(
fragmentActivity = this@HomeActivity,
deepLink = permalink,
navigationInterceptor = this@HomeActivity,
buildTask = true
)
}
}

private fun askUserToSelectPushDistributor() {
unifiedPushHelper.showSelectDistributorDialog(this) { selection ->
homeActivityViewModel.handle(HomeActivityViewActions.RegisterPushDistributor(selection))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
object StartRecoverySetupFlow : HomeActivityViewEvents
data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents
object AskUserForPushDistributor : HomeActivityViewEvents
data class NavigatePermalink(val permalink: String) : HomeActivityViewEvents
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ class HomeActivityViewModel @AssistedInject constructor(
.onEach { status ->
when (status) {
is SyncRequestState.Idle -> {
checkDeferredPermalink()
maybeVerifyOrBootstrapCrossSigning()
}
else -> Unit
Expand Down Expand Up @@ -371,6 +372,12 @@ class HomeActivityViewModel @AssistedInject constructor(
}
}

private fun checkDeferredPermalink() {
activeSessionHolder.getActiveSession().deferredPermalinkService().getLinkFromClipBoard()?.let { roomPermalink ->
_viewEvents.post(HomeActivityViewEvents.NavigatePermalink(permalink = roomPermalink))
}
}

private fun maybeVerifyOrBootstrapCrossSigning() {
// The contents of this method should only run once
if (hasCheckedBootstrap) return
Expand Down

0 comments on commit 2dc103f

Please sign in to comment.