From 9b8800ec559c032f1062566871f32ea1863b4926 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Dec 2018 19:08:30 +0100 Subject: [PATCH] Permalinks : add a parser to get data from permalink (userId, eventId...) --- .../home/room/detail/RoomDetailFragment.kt | 4 +- .../home/room/detail/timeline/MessageItem.kt | 6 +-- .../{MatrixUrlLinkify.kt => MatrixLinkify.kt} | 8 +-- ...atrixURLSpan.kt => MatrixPermalinkSpan.kt} | 4 +- .../android/api/permalinks/PermalinkData.kt | 17 +++++++ ...{PermalinkUtils.kt => PermalinkFactory.kt} | 2 +- .../android/api/permalinks/PermalinkParser.kt | 50 +++++++++++++++++++ 7 files changed, 80 insertions(+), 11 deletions(-) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/{MatrixUrlLinkify.kt => MatrixLinkify.kt} (88%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/{MatrixURLSpan.kt => MatrixPermalinkSpan.kt} (66%) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkData.kt rename matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/{PermalinkUtils.kt => PermalinkFactory.kt} (98%) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkParser.kt diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt index 42823a75..d493d3e0 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.ViewGroup import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.permalinks.PermalinkParser import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.Room @@ -105,7 +106,8 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback { // TimelineEventController.Callback ************************************************************ override fun onUrlClicked(url: String) { - Timber.v("Url clicked: $url") + val permalinkData = PermalinkParser.parse(url) + Timber.v("Permalink data : $permalinkData") } } diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt index fb7ac6dd..44a9b2f6 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt @@ -3,8 +3,8 @@ package im.vector.riotredesign.features.home.room.detail.timeline import android.view.View import android.widget.ImageView import android.widget.TextView -import im.vector.matrix.android.api.permalinks.MatrixURLSpan -import im.vector.matrix.android.api.permalinks.MatrixUrlLinkify +import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan +import im.vector.matrix.android.api.permalinks.MatrixLinkify import im.vector.riotredesign.R import im.vector.riotredesign.core.epoxy.KotlinModel import im.vector.riotredesign.features.home.AvatarRenderer @@ -25,7 +25,7 @@ data class MessageItem( override fun bind() { messageView.text = message - MatrixUrlLinkify.addLinks(messageView, object : MatrixURLSpan.Callback { + MatrixLinkify.addLinks(messageView, object : MatrixPermalinkSpan.Callback { override fun onUrlClicked(url: String) { onUrlClickedListener?.invoke(url) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixUrlLinkify.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixLinkify.kt similarity index 88% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixUrlLinkify.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixLinkify.kt index fe6de865..ff72254f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixUrlLinkify.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixLinkify.kt @@ -5,14 +5,14 @@ import android.text.SpannableString import android.text.method.LinkMovementMethod import android.widget.TextView -object MatrixUrlLinkify { +object MatrixLinkify { /** * Find the matrix spans i.e matrix id , user id ... to display them as URL. * * @param spannable the text in which the matrix items has to be clickable. */ - fun addLinks(spannable: Spannable?, callback: MatrixURLSpan.Callback?): Boolean { + fun addLinks(spannable: Spannable?, callback: MatrixPermalinkSpan.Callback?): Boolean { // sanity checks if (spannable.isNullOrEmpty()) { return false @@ -28,7 +28,7 @@ object MatrixUrlLinkify { if (startPos == 0 || text[startPos - 1] != '/') { val endPos = matcher.end(0) val url = text.substring(matcher.start(0), matcher.end(0)) - val span = MatrixURLSpan(url, callback) + val span = MatrixPermalinkSpan(url, callback) spannable.setSpan(span, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } } @@ -36,7 +36,7 @@ object MatrixUrlLinkify { return hasMatch } - fun addLinks(textView: TextView, callback: MatrixURLSpan.Callback?): Boolean { + fun addLinks(textView: TextView, callback: MatrixPermalinkSpan.Callback?): Boolean { val text = textView.text if (text is Spannable) { if (addLinks(text, callback)) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixURLSpan.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixPermalinkSpan.kt similarity index 66% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixURLSpan.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixPermalinkSpan.kt index cceba501..53ab671c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixURLSpan.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/MatrixPermalinkSpan.kt @@ -3,8 +3,8 @@ package im.vector.matrix.android.api.permalinks import android.text.style.ClickableSpan import android.view.View -class MatrixURLSpan(private val url: String, - private val callback: Callback? = null) : ClickableSpan() { +class MatrixPermalinkSpan(private val url: String, + private val callback: Callback? = null) : ClickableSpan() { interface Callback { fun onUrlClicked(url: String) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkData.kt new file mode 100644 index 00000000..29b00bc9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkData.kt @@ -0,0 +1,17 @@ +package im.vector.matrix.android.api.permalinks + +import android.net.Uri + +sealed class PermalinkData { + + data class EventLink(val roomIdOrAlias: String, val eventId: String) : PermalinkData() + + data class RoomLink(val roomIdOrAlias: String) : PermalinkData() + + data class UserLink(val userId: String) : PermalinkData() + + data class GroupLink(val groupId: String) : PermalinkData() + + data class FallbackLink(val uri: Uri) : PermalinkData() + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkFactory.kt similarity index 98% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkUtils.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkFactory.kt index 2bde654a..c9ebe44f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkFactory.kt @@ -6,7 +6,7 @@ import im.vector.matrix.android.api.session.events.model.Event /** * Useful methods to deals with Matrix permalink */ -object PermalinkUtils { +object PermalinkFactory { private val MATRIX_TO_URL_BASE = "https://matrix.to/#/" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkParser.kt new file mode 100644 index 00000000..07cba499 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/permalinks/PermalinkParser.kt @@ -0,0 +1,50 @@ +package im.vector.matrix.android.api.permalinks + +import android.net.Uri + +object PermalinkParser { + + private const val MATRIX_NAVIGATE_TO_HOST = "matrix.to" + + fun parse(uriString: String): PermalinkData { + val uri = Uri.parse(uriString) + return parse(uri) + } + + fun parse(uri: Uri): PermalinkData { + val host = uri.host + val path = uri.path + val fragment = uri.fragment + + if (path.isNullOrEmpty() + || host.isNullOrEmpty() + || fragment.isNullOrEmpty() + || host != MATRIX_NAVIGATE_TO_HOST) { + return PermalinkData.FallbackLink(uri) + } + // we are limiting to 2 params + val params = fragment + .split(MatrixPatterns.SEP_REGEX.toRegex()) + .filter { it.isNotEmpty() } + .take(2) + + val identifier = params.getOrNull(0) + val extraParameter = params.getOrNull(1) + if (identifier.isNullOrEmpty()) { + return PermalinkData.FallbackLink(uri) + } + return when { + MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier) + MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier) + MatrixPatterns.isRoomId(identifier) -> { + if (!extraParameter.isNullOrEmpty() && MatrixPatterns.isEventId(extraParameter)) { + PermalinkData.EventLink(roomIdOrAlias = identifier, eventId = extraParameter) + } else { + PermalinkData.RoomLink(roomIdOrAlias = identifier) + } + } + else -> PermalinkData.FallbackLink(uri) + } + } + +} \ No newline at end of file