Skip to content

Commit 110b5cf

Browse files
authored
Add pills for permalink supported hosts (#8324)
1 parent fb837fe commit 110b5cf

File tree

8 files changed

+44
-18
lines changed

8 files changed

+44
-18
lines changed

changelog.d/8307.bugfix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The new permalink rendering is not applied on permalink created with the potential clientPermalinkBaseUrl
2+

matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/TestPermalinkService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,8 @@ class TestPermalinkService : PermalinkService {
4848
MARKDOWN -> "[%2\$s](https://matrix.to/#/%1\$s)"
4949
}
5050
}
51+
52+
override fun isPermalinkSupported(supportedHosts: Array<String>, url: String): Boolean {
53+
return false
54+
}
5155
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ object MatrixPatterns {
6262
// regex pattern to find permalink with message id.
6363
// Android does not support in URL so extract it.
6464
private const val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/"
65-
private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/"
65+
private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/#/(room|user)/"
6666
const val SEP_REGEX = "/"
6767

6868
private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK = PERMALINK_BASE_REGEX.toRegex(RegexOption.IGNORE_CASE)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,15 @@ interface PermalinkService {
9797
* @return the created template
9898
*/
9999
fun createMentionSpanTemplate(type: SpanTemplateType, forceMatrixTo: Boolean = false): String
100+
101+
/**
102+
* Check if the url is a permalink. It must be a matrix.to link
103+
* or a link with host provided by the string-array `permalink_supported_hosts` in the config file
104+
*
105+
* @param supportedHosts the list of hosts supported for permalinks
106+
* @param url the link to check, Ex: "https://matrix.to/#/@benoit:matrix.org"
107+
*
108+
* @return true when url is a permalink
109+
*/
110+
fun isPermalinkSupported(supportedHosts: Array<String>, url: String): Boolean
100111
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.matrix.android.sdk.internal.session.permalinks
1818

19+
import androidx.core.net.toUri
1920
import org.matrix.android.sdk.api.session.events.model.Event
2021
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
2122
import javax.inject.Inject
@@ -47,4 +48,9 @@ internal class DefaultPermalinkService @Inject constructor(
4748
override fun createMentionSpanTemplate(type: PermalinkService.SpanTemplateType, forceMatrixTo: Boolean): String {
4849
return permalinkFactory.createMentionSpanTemplate(type, forceMatrixTo)
4950
}
51+
52+
override fun isPermalinkSupported(supportedHosts: Array<String>, url: String): Boolean {
53+
return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) ||
54+
supportedHosts.any { url.toUri().host == it }
55+
}
5056
}

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import im.vector.app.core.di.ActiveSessionHolder
2929
import im.vector.app.core.glide.GlideApp
3030
import im.vector.app.features.home.AvatarRenderer
3131
import im.vector.app.features.html.PillImageSpan
32-
import org.matrix.android.sdk.api.MatrixPatterns
32+
import org.matrix.android.sdk.api.extensions.orFalse
3333
import org.matrix.android.sdk.api.session.getRoomSummary
3434
import org.matrix.android.sdk.api.session.getUserOrDefault
3535
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
@@ -99,7 +99,9 @@ class EventTextRenderer @AssistedInject constructor(
9999
private fun addPermalinksSpans(text: Spannable) {
100100
for (match in Patterns.WEB_URL.toRegex().findAll(text)) {
101101
val url = text.substring(match.range)
102-
val matrixItem = if (MatrixPatterns.isPermalink(url)) {
102+
val supportedHosts = context.resources.getStringArray(R.array.permalink_supported_hosts)
103+
val isPermalinkSupported = sessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, url).orFalse()
104+
val matrixItem = if (isPermalinkSupported) {
103105
when (val permalinkData = PermalinkParser.parse(url)) {
104106
is PermalinkData.UserLink -> permalinkData.toMatrixItem()
105107
is PermalinkData.RoomLink -> permalinkData.toMatrixItem()

vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import android.text.Spanned
2222
import dagger.assisted.Assisted
2323
import dagger.assisted.AssistedFactory
2424
import dagger.assisted.AssistedInject
25+
import im.vector.app.R
2526
import im.vector.app.core.di.ActiveSessionHolder
2627
import im.vector.app.core.glide.GlideApp
2728
import im.vector.app.features.home.AvatarRenderer
2829
import io.noties.markwon.core.spans.LinkSpan
30+
import org.matrix.android.sdk.api.extensions.orFalse
2931
import org.matrix.android.sdk.api.session.getRoomSummary
3032
import org.matrix.android.sdk.api.session.getUser
3133
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
@@ -105,12 +107,18 @@ class PillsPostProcessor @AssistedInject constructor(
105107
PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem)
106108

107109
private fun LinkSpan.createPillSpan(): PillImageSpan? {
108-
val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) {
109-
is PermalinkData.UserLink -> permalinkData.toMatrixItem()
110-
is PermalinkData.RoomLink -> permalinkData.toMatrixItem()
111-
else -> null
112-
} ?: return null
113-
return createPillImageSpan(matrixItem)
110+
val supportedHosts = context.resources.getStringArray(R.array.permalink_supported_hosts)
111+
val isPermalinkSupported = sessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, url).orFalse()
112+
if (isPermalinkSupported) {
113+
val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) {
114+
is PermalinkData.UserLink -> permalinkData.toMatrixItem()
115+
is PermalinkData.RoomLink -> permalinkData.toMatrixItem()
116+
else -> null
117+
} ?: return null
118+
return createPillImageSpan(matrixItem)
119+
} else {
120+
return null
121+
}
114122
}
115123

116124
private fun PermalinkData.UserLink.toMatrixItem(): MatrixItem? =

vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package im.vector.app.features.permalink
1818

1919
import android.content.Context
2020
import android.net.Uri
21-
import androidx.core.net.toUri
2221
import androidx.fragment.app.FragmentActivity
2322
import im.vector.app.R
2423
import im.vector.app.core.di.ActiveSessionHolder
@@ -38,7 +37,6 @@ import org.matrix.android.sdk.api.session.getRoom
3837
import org.matrix.android.sdk.api.session.getRoomSummary
3938
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
4039
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
41-
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
4240
import org.matrix.android.sdk.api.session.room.getTimelineEvent
4341
import org.matrix.android.sdk.api.session.room.model.Membership
4442
import org.matrix.android.sdk.api.session.room.model.RoomSummary
@@ -68,10 +66,11 @@ class PermalinkHandler @Inject constructor(
6866
navigationInterceptor: NavigationInterceptor? = null,
6967
buildTask: Boolean = false
7068
): Boolean {
69+
val supportedHosts = fragmentActivity.resources.getStringArray(R.array.permalink_supported_hosts)
7170
return when {
7271
deepLink == null -> false
7372
deepLink.isIgnored() -> true
74-
!isPermalinkSupported(fragmentActivity, deepLink.toString()) -> false
73+
!activeSessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, deepLink.toString()).orFalse() -> false
7574
else -> {
7675
tryOrNull {
7776
withContext(Dispatchers.Default) {
@@ -167,12 +166,6 @@ class PermalinkHandler @Inject constructor(
167166
}
168167
}
169168

170-
private fun isPermalinkSupported(context: Context, url: String): Boolean {
171-
return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) ||
172-
context.resources.getStringArray(R.array.permalink_supported_hosts)
173-
.any { url.toUri().host == it }
174-
}
175-
176169
private suspend fun PermalinkData.RoomLink.getRoomId(): String? {
177170
val session = activeSessionHolder.getSafeActiveSession()
178171
return if (isRoomAlias && session != null) {

0 commit comments

Comments
 (0)