Use SDK API to build room and event permalinks.
This commit is contained in:
parent
f99670eae3
commit
4c7e66e928
9 changed files with 37 additions and 109 deletions
|
|
@ -236,7 +236,7 @@ class MessagesPresenterTest {
|
||||||
val clipboardHelper = FakeClipboardHelper()
|
val clipboardHelper = FakeClipboardHelper()
|
||||||
val event = aMessageEvent()
|
val event = aMessageEvent()
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
permalinkResult = { Result.success("a link") },
|
eventPermalinkResult = { Result.success("a link") },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(
|
val presenter = createMessagesPresenter(
|
||||||
clipboardHelper = clipboardHelper,
|
clipboardHelper = clipboardHelper,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomdetails.impl
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import com.bumble.appyx.core.lifecycle.subscribe
|
import com.bumble.appyx.core.lifecycle.subscribe
|
||||||
|
|
@ -35,6 +36,8 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import io.element.android.libraries.androidutils.R as AndroidUtilsR
|
import io.element.android.libraries.androidutils.R as AndroidUtilsR
|
||||||
|
|
||||||
|
|
@ -83,20 +86,18 @@ class RoomDetailsNode @AssistedInject constructor(
|
||||||
callbacks.forEach { it.openPollHistory() }
|
callbacks.forEach { it.openPollHistory() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onShareRoom(context: Context) {
|
private fun CoroutineScope.onShareRoom(context: Context) = launch {
|
||||||
val alias = room.alias ?: room.alternativeAliases.firstOrNull()
|
room.getPermalink()
|
||||||
val permalinkResult = alias?.let { permalinkBuilder.permalinkForRoomAlias(it) }
|
.onSuccess { permalink ->
|
||||||
?: permalinkBuilder.permalinkForRoomId(room.roomId)
|
context.startSharePlainTextIntent(
|
||||||
permalinkResult.onSuccess { permalink ->
|
activityResultLauncher = null,
|
||||||
context.startSharePlainTextIntent(
|
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
|
||||||
activityResultLauncher = null,
|
text = permalink,
|
||||||
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
|
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
|
||||||
text = permalink,
|
)
|
||||||
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
|
}.onFailure {
|
||||||
)
|
Timber.e(it)
|
||||||
}.onFailure {
|
}
|
||||||
Timber.e(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onShareMember(context: Context, member: RoomMember) {
|
private fun onShareMember(context: Context, member: RoomMember) {
|
||||||
|
|
@ -129,9 +130,10 @@ class RoomDetailsNode @AssistedInject constructor(
|
||||||
override fun View(modifier: Modifier) {
|
override fun View(modifier: Modifier) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
fun onShareRoom() {
|
fun onShareRoom() {
|
||||||
this.onShareRoom(context)
|
coroutineScope.onShareRoom(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onShareMember(roomMember: RoomMember) {
|
fun onShareMember(roomMember: RoomMember) {
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,12 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.permalink
|
package io.element.android.libraries.matrix.api.permalink
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
|
||||||
interface PermalinkBuilder {
|
interface PermalinkBuilder {
|
||||||
fun permalinkForUser(userId: UserId): Result<String>
|
fun permalinkForUser(userId: UserId): Result<String>
|
||||||
fun permalinkForRoomAlias(roomAlias: String): Result<String>
|
|
||||||
fun permalinkForRoomId(roomId: RoomId): Result<String>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class PermalinkBuilderError : Throwable() {
|
sealed class PermalinkBuilderError : Throwable() {
|
||||||
data object InvalidRoomAlias : PermalinkBuilderError()
|
|
||||||
data object InvalidRoomId : PermalinkBuilderError()
|
|
||||||
data object InvalidUserId : PermalinkBuilderError()
|
data object InvalidUserId : PermalinkBuilderError()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,11 @@ interface MatrixRoom : Closeable {
|
||||||
*/
|
*/
|
||||||
fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result<MatrixWidgetDriver>
|
fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result<MatrixWidgetDriver>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the permalink for the room.
|
||||||
|
*/
|
||||||
|
suspend fun getPermalink(): Result<String>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the permalink for the provided [eventId].
|
* Get the permalink for the provided [eventId].
|
||||||
* @param eventId The event id to get the permalink for.
|
* @param eventId The event id to get the permalink for.
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.appconfig.MatrixConfiguration
|
import io.element.android.appconfig.MatrixConfiguration
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
import io.element.android.libraries.matrix.api.core.MatrixPatterns
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilderError
|
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilderError
|
||||||
|
|
@ -54,39 +53,9 @@ class DefaultPermalinkBuilder @Inject constructor() : PermalinkBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun permalinkForRoomAlias(roomAlias: String): Result<String> {
|
|
||||||
return if (MatrixPatterns.isRoomAlias(roomAlias)) {
|
|
||||||
Result.success(permalinkForRoomAliasOrId(roomAlias))
|
|
||||||
} else {
|
|
||||||
Result.failure(PermalinkBuilderError.InvalidRoomAlias)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun permalinkForRoomId(roomId: RoomId): Result<String> {
|
|
||||||
return if (MatrixPatterns.isRoomId(roomId.value)) {
|
|
||||||
Result.success(permalinkForRoomAliasOrId(roomId.value))
|
|
||||||
} else {
|
|
||||||
Result.failure(PermalinkBuilderError.InvalidRoomId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun permalinkForRoomAliasOrId(value: String): String {
|
|
||||||
val id = escapeId(value)
|
|
||||||
return buildString {
|
|
||||||
append(permalinkBaseUrl)
|
|
||||||
if (!isMatrixTo()) {
|
|
||||||
append(ROOM_PATH)
|
|
||||||
}
|
|
||||||
append(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun escapeId(value: String) = value.replace("/", "%2F")
|
|
||||||
|
|
||||||
private fun isMatrixTo(): Boolean = permalinkBaseUrl.startsWith(MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL)
|
private fun isMatrixTo(): Boolean = permalinkBaseUrl.startsWith(MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ROOM_PATH = "room/"
|
|
||||||
private const val USER_PATH = "user/"
|
private const val USER_PATH = "user/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.impl.room
|
package io.element.android.libraries.matrix.impl.room
|
||||||
|
|
||||||
import io.element.android.appconfig.MatrixConfiguration
|
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.core.coroutine.childScope
|
import io.element.android.libraries.core.coroutine.childScope
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
|
@ -731,17 +730,12 @@ class RustMatrixRoom(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getPermalinkFor(eventId: EventId): Result<String> {
|
override suspend fun getPermalink(): Result<String> = runCatching {
|
||||||
// FIXME Use the SDK API once https://github.com/matrix-org/matrix-rust-sdk/issues/3259 has been done
|
innerRoom.matrixToPermalink()
|
||||||
// Now use a simple builder
|
}
|
||||||
return runCatching {
|
|
||||||
buildString {
|
override suspend fun getPermalinkFor(eventId: EventId): Result<String> = runCatching {
|
||||||
append(MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL)
|
innerRoom.matrixToEventPermalink(eventId.value)
|
||||||
append(roomId.value)
|
|
||||||
append("/")
|
|
||||||
append(eventId.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendAttachment(files: List<File>, handle: () -> SendAttachmentJoinHandle): Result<MediaUploadHandler> {
|
private fun sendAttachment(files: List<File>, handle: () -> SendAttachmentJoinHandle): Result<MediaUploadHandler> {
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ package io.element.android.libraries.matrix.impl.permalink
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.androidutils.metadata.withReleaseBehavior
|
import io.element.android.libraries.androidutils.metadata.withReleaseBehavior
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.tests.testutils.assertThrowsInDebug
|
import io.element.android.tests.testutils.assertThrowsInDebug
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class DefaultPermalinkBuilderTest {
|
class DefaultPermalinkBuilderTest {
|
||||||
|
@Test
|
||||||
fun `building a permalink for an invalid user id throws when verifying the id`() {
|
fun `building a permalink for an invalid user id throws when verifying the id`() {
|
||||||
assertThrowsInDebug {
|
assertThrowsInDebug {
|
||||||
val userId = UserId("some invalid user id")
|
val userId = UserId("some invalid user id")
|
||||||
|
|
@ -31,13 +31,6 @@ class DefaultPermalinkBuilderTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun `building a permalink for an invalid room id throws when verifying the id`() {
|
|
||||||
assertThrowsInDebug {
|
|
||||||
val roomId = RoomId("some invalid room id")
|
|
||||||
DefaultPermalinkBuilder().permalinkForRoomId(roomId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `building a permalink for an invalid user id returns failure when not verifying the id`() {
|
fun `building a permalink for an invalid user id returns failure when not verifying the id`() {
|
||||||
withReleaseBehavior {
|
withReleaseBehavior {
|
||||||
|
|
@ -46,35 +39,9 @@ class DefaultPermalinkBuilderTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `building a permalink for an invalid room id returns failure when not verifying the id`() {
|
|
||||||
withReleaseBehavior {
|
|
||||||
val roomId = RoomId("some invalid room id")
|
|
||||||
assertThat(DefaultPermalinkBuilder().permalinkForRoomId(roomId).isFailure).isTrue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `building a permalink for an invalid room alias returns failure`() {
|
|
||||||
val roomAlias = "an invalid room alias"
|
|
||||||
assertThat(DefaultPermalinkBuilder().permalinkForRoomAlias(roomAlias).isFailure).isTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `building a permalink for a valid user id returns a matrix-to url`() {
|
fun `building a permalink for a valid user id returns a matrix-to url`() {
|
||||||
val userId = UserId("@user:matrix.org")
|
val userId = UserId("@user:matrix.org")
|
||||||
assertThat(DefaultPermalinkBuilder().permalinkForUser(userId).getOrNull()).isEqualTo("https://matrix.to/#/@user:matrix.org")
|
assertThat(DefaultPermalinkBuilder().permalinkForUser(userId).getOrNull()).isEqualTo("https://matrix.to/#/@user:matrix.org")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `building a permalink for a valid room id returns a matrix-to url`() {
|
|
||||||
val roomId = RoomId("!aBCdEFG1234:matrix.org")
|
|
||||||
assertThat(DefaultPermalinkBuilder().permalinkForRoomId(roomId).getOrNull()).isEqualTo("https://matrix.to/#/!aBCdEFG1234:matrix.org")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `building a permalink for a valid room alias returns a matrix-to url`() {
|
|
||||||
val roomAlias = "#room:matrix.org"
|
|
||||||
assertThat(DefaultPermalinkBuilder().permalinkForRoomAlias(roomAlias).getOrNull()).isEqualTo("https://matrix.to/#/#room:matrix.org")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.test.permalink
|
package io.element.android.libraries.matrix.test.permalink
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
||||||
|
|
||||||
|
|
@ -26,12 +25,4 @@ class FakePermalinkBuilder(
|
||||||
override fun permalinkForUser(userId: UserId): Result<String> {
|
override fun permalinkForUser(userId: UserId): Result<String> {
|
||||||
return result()
|
return result()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun permalinkForRoomAlias(roomAlias: String): Result<String> {
|
|
||||||
return result()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun permalinkForRoomId(roomId: RoomId): Result<String> {
|
|
||||||
return result()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,8 @@ class FakeMatrixRoom(
|
||||||
override val activeMemberCount: Long = 234L,
|
override val activeMemberCount: Long = 234L,
|
||||||
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
|
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
|
||||||
private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(),
|
private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(),
|
||||||
private var permalinkResult: () -> Result<String> = { Result.success("link") },
|
private var roomPermalinkResult: () -> Result<String> = { Result.success("room link") },
|
||||||
|
private var eventPermalinkResult: (EventId) -> Result<String> = { Result.success("event link") },
|
||||||
canRedactOwn: Boolean = false,
|
canRedactOwn: Boolean = false,
|
||||||
canRedactOther: Boolean = false,
|
canRedactOther: Boolean = false,
|
||||||
) : MatrixRoom {
|
) : MatrixRoom {
|
||||||
|
|
@ -278,8 +279,12 @@ class FakeMatrixRoom(
|
||||||
return cancelSendResult
|
return cancelSendResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getPermalink(): Result<String> {
|
||||||
|
return roomPermalinkResult()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getPermalinkFor(eventId: EventId): Result<String> {
|
override suspend fun getPermalinkFor(eventId: EventId): Result<String> {
|
||||||
return permalinkResult()
|
return eventPermalinkResult(eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue