Skip to content

Commit 89d2f43

Browse files
authored
Merge pull request #2708 from element-hq/feature/bma/sdkPermalink
Use sdk API to build permalinks
2 parents 7b14a0e + 9fcb880 commit 89d2f43

File tree

10 files changed

+54
-193
lines changed

10 files changed

+54
-193
lines changed

changelog.d/2708.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use sdk API to build permalinks

features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class MessagesPresenterTest {
236236
val clipboardHelper = FakeClipboardHelper()
237237
val event = aMessageEvent()
238238
val matrixRoom = FakeMatrixRoom(
239-
permalinkResult = { Result.success("a link") },
239+
eventPermalinkResult = { Result.success("a link") },
240240
)
241241
val presenter = createMessagesPresenter(
242242
clipboardHelper = clipboardHelper,

features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import android.content.Context
2020
import androidx.compose.runtime.Composable
2121
import androidx.compose.ui.Modifier
2222
import androidx.compose.ui.platform.LocalContext
23+
import androidx.lifecycle.lifecycleScope
2324
import com.bumble.appyx.core.lifecycle.subscribe
2425
import com.bumble.appyx.core.modality.BuildContext
2526
import com.bumble.appyx.core.node.Node
@@ -35,6 +36,8 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
3536
import io.element.android.libraries.matrix.api.room.MatrixRoom
3637
import io.element.android.libraries.matrix.api.room.RoomMember
3738
import io.element.android.services.analytics.api.AnalyticsService
39+
import kotlinx.coroutines.CoroutineScope
40+
import kotlinx.coroutines.launch
3841
import timber.log.Timber
3942
import io.element.android.libraries.androidutils.R as AndroidUtilsR
4043

@@ -83,34 +86,35 @@ class RoomDetailsNode @AssistedInject constructor(
8386
callbacks.forEach { it.openPollHistory() }
8487
}
8588

86-
private fun onShareRoom(context: Context) {
87-
val alias = room.alias ?: room.alternativeAliases.firstOrNull()
88-
val permalinkResult = alias?.let { permalinkBuilder.permalinkForRoomAlias(it) }
89-
?: permalinkBuilder.permalinkForRoomId(room.roomId)
90-
permalinkResult.onSuccess { permalink ->
91-
context.startSharePlainTextIntent(
92-
activityResultLauncher = null,
93-
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
94-
text = permalink,
95-
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
96-
)
97-
}.onFailure {
98-
Timber.e(it)
99-
}
89+
private fun CoroutineScope.onShareRoom(context: Context) = launch {
90+
room.getPermalink()
91+
.onSuccess { permalink ->
92+
context.startSharePlainTextIntent(
93+
activityResultLauncher = null,
94+
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
95+
text = permalink,
96+
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
97+
)
98+
}
99+
.onFailure {
100+
Timber.e(it)
101+
}
100102
}
101103

102104
private fun onShareMember(context: Context, member: RoomMember) {
103105
val permalinkResult = permalinkBuilder.permalinkForUser(member.userId)
104-
permalinkResult.onSuccess { permalink ->
105-
context.startSharePlainTextIntent(
106-
activityResultLauncher = null,
107-
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
108-
text = permalink,
109-
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
110-
)
111-
}.onFailure {
112-
Timber.e(it)
113-
}
106+
permalinkResult
107+
.onSuccess { permalink ->
108+
context.startSharePlainTextIntent(
109+
activityResultLauncher = null,
110+
chooserTitle = context.getString(R.string.screen_room_details_share_room_title),
111+
text = permalink,
112+
noActivityFoundMessage = context.getString(AndroidUtilsR.string.error_no_compatible_app_found)
113+
)
114+
}
115+
.onFailure {
116+
Timber.e(it)
117+
}
114118
}
115119

116120
private fun onEditRoomDetails() {
@@ -131,7 +135,7 @@ class RoomDetailsNode @AssistedInject constructor(
131135
val state = presenter.present()
132136

133137
fun onShareRoom() {
134-
this.onShareRoom(context)
138+
lifecycleScope.onShareRoom(context)
135139
}
136140

137141
fun onShareMember(roomMember: RoomMember) {

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkBuilder.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,12 @@
1616

1717
package io.element.android.libraries.matrix.api.permalink
1818

19-
import io.element.android.libraries.matrix.api.core.RoomId
2019
import io.element.android.libraries.matrix.api.core.UserId
2120

2221
interface PermalinkBuilder {
2322
fun permalinkForUser(userId: UserId): Result<String>
24-
fun permalinkForRoomAlias(roomAlias: String): Result<String>
25-
fun permalinkForRoomId(roomId: RoomId): Result<String>
2623
}
2724

2825
sealed class PermalinkBuilderError : Throwable() {
29-
data object InvalidRoomAlias : PermalinkBuilderError()
30-
data object InvalidRoomId : PermalinkBuilderError()
3126
data object InvalidUserId : PermalinkBuilderError()
3227
}

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ interface MatrixRoom : Closeable {
317317
*/
318318
fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result<MatrixWidgetDriver>
319319

320+
/**
321+
* Get the permalink for the room.
322+
*/
323+
suspend fun getPermalink(): Result<String>
324+
320325
/**
321326
* Get the permalink for the provided [eventId].
322327
* @param eventId The event id to get the permalink for.

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/permalink/DefaultPermalinkBuilder.kt

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,76 +17,22 @@
1717
package io.element.android.libraries.matrix.impl.permalink
1818

1919
import com.squareup.anvil.annotations.ContributesBinding
20-
import io.element.android.appconfig.MatrixConfiguration
2120
import io.element.android.libraries.di.AppScope
2221
import io.element.android.libraries.matrix.api.core.MatrixPatterns
23-
import io.element.android.libraries.matrix.api.core.RoomId
2422
import io.element.android.libraries.matrix.api.core.UserId
2523
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
2624
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilderError
25+
import org.matrix.rustcomponents.sdk.matrixToUserPermalink
2726
import javax.inject.Inject
2827

2928
@ContributesBinding(AppScope::class)
3029
class DefaultPermalinkBuilder @Inject constructor() : PermalinkBuilder {
31-
private val permalinkBaseUrl
32-
get() = (MatrixConfiguration.clientPermalinkBaseUrl ?: MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL).also {
33-
var baseUrl = it
34-
if (!baseUrl.endsWith("/")) {
35-
baseUrl += "/"
36-
}
37-
if (!baseUrl.endsWith("/#/")) {
38-
baseUrl += "/#/"
39-
}
40-
}
41-
4230
override fun permalinkForUser(userId: UserId): Result<String> {
43-
return if (MatrixPatterns.isUserId(userId.value)) {
44-
val url = buildString {
45-
append(permalinkBaseUrl)
46-
if (!isMatrixTo()) {
47-
append(USER_PATH)
48-
}
49-
append(userId.value)
50-
}
51-
Result.success(url)
52-
} else {
53-
Result.failure(PermalinkBuilderError.InvalidUserId)
54-
}
55-
}
56-
57-
override fun permalinkForRoomAlias(roomAlias: String): Result<String> {
58-
return if (MatrixPatterns.isRoomAlias(roomAlias)) {
59-
Result.success(permalinkForRoomAliasOrId(roomAlias))
60-
} else {
61-
Result.failure(PermalinkBuilderError.InvalidRoomAlias)
62-
}
63-
}
64-
65-
override fun permalinkForRoomId(roomId: RoomId): Result<String> {
66-
return if (MatrixPatterns.isRoomId(roomId.value)) {
67-
Result.success(permalinkForRoomAliasOrId(roomId.value))
68-
} else {
69-
Result.failure(PermalinkBuilderError.InvalidRoomId)
31+
if (!MatrixPatterns.isUserId(userId.value)) {
32+
return Result.failure(PermalinkBuilderError.InvalidUserId)
7033
}
71-
}
72-
73-
private fun permalinkForRoomAliasOrId(value: String): String {
74-
val id = escapeId(value)
75-
return buildString {
76-
append(permalinkBaseUrl)
77-
if (!isMatrixTo()) {
78-
append(ROOM_PATH)
79-
}
80-
append(id)
34+
return runCatching {
35+
matrixToUserPermalink(userId.value)
8136
}
8237
}
83-
84-
private fun escapeId(value: String) = value.replace("/", "%2F")
85-
86-
private fun isMatrixTo(): Boolean = permalinkBaseUrl.startsWith(MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL)
87-
88-
companion object {
89-
private const val ROOM_PATH = "room/"
90-
private const val USER_PATH = "user/"
91-
}
9238
}

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt

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

1717
package io.element.android.libraries.matrix.impl.room
1818

19-
import io.element.android.appconfig.MatrixConfiguration
2019
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
2120
import io.element.android.libraries.core.coroutine.childScope
2221
import io.element.android.libraries.matrix.api.core.EventId
@@ -731,17 +730,12 @@ class RustMatrixRoom(
731730
)
732731
}
733732

734-
override suspend fun getPermalinkFor(eventId: EventId): Result<String> {
735-
// FIXME Use the SDK API once https://github.com/matrix-org/matrix-rust-sdk/issues/3259 has been done
736-
// Now use a simple builder
737-
return runCatching {
738-
buildString {
739-
append(MatrixConfiguration.MATRIX_TO_PERMALINK_BASE_URL)
740-
append(roomId.value)
741-
append("/")
742-
append(eventId.value)
743-
}
744-
}
733+
override suspend fun getPermalink(): Result<String> = runCatching {
734+
innerRoom.matrixToPermalink()
735+
}
736+
737+
override suspend fun getPermalinkFor(eventId: EventId): Result<String> = runCatching {
738+
innerRoom.matrixToEventPermalink(eventId.value)
745739
}
746740

747741
private fun sendAttachment(files: List<File>, handle: () -> SendAttachmentJoinHandle): Result<MediaUploadHandler> {

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/permalink/DefaultPermalinkBuilderTest.kt

Lines changed: 0 additions & 80 deletions
This file was deleted.

libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/permalink/FakePermalinkBuilder.kt

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

1717
package io.element.android.libraries.matrix.test.permalink
1818

19-
import io.element.android.libraries.matrix.api.core.RoomId
2019
import io.element.android.libraries.matrix.api.core.UserId
2120
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
2221

@@ -26,12 +25,4 @@ class FakePermalinkBuilder(
2625
override fun permalinkForUser(userId: UserId): Result<String> {
2726
return result()
2827
}
29-
30-
override fun permalinkForRoomAlias(roomAlias: String): Result<String> {
31-
return result()
32-
}
33-
34-
override fun permalinkForRoomId(roomId: RoomId): Result<String> {
35-
return result()
36-
}
3728
}

libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class FakeMatrixRoom(
8484
override val activeMemberCount: Long = 234L,
8585
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
8686
private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(),
87-
private var permalinkResult: () -> Result<String> = { Result.success("link") },
87+
private var roomPermalinkResult: () -> Result<String> = { Result.success("room link") },
88+
private var eventPermalinkResult: (EventId) -> Result<String> = { Result.success("event link") },
8889
canRedactOwn: Boolean = false,
8990
canRedactOther: Boolean = false,
9091
) : MatrixRoom {
@@ -278,8 +279,12 @@ class FakeMatrixRoom(
278279
return cancelSendResult
279280
}
280281

282+
override suspend fun getPermalink(): Result<String> {
283+
return roomPermalinkResult()
284+
}
285+
281286
override suspend fun getPermalinkFor(eventId: EventId): Result<String> {
282-
return permalinkResult()
287+
return eventPermalinkResult(eventId)
283288
}
284289

285290
override suspend fun editMessage(

0 commit comments

Comments
 (0)