Permalinks : add a parser to get data from permalink (userId, eventId...)

This commit is contained in:
ganfra 2018-12-19 19:08:30 +01:00
parent fdd4642cbb
commit 9b8800ec55
7 changed files with 80 additions and 11 deletions

View File

@ -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")
}

}

View File

@ -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)
}

View File

@ -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)) {

View File

@ -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)

View File

@ -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()

}

View File

@ -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/#/"

View File

@ -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)
}
}

}