Skip to content

Commit 6e2f645

Browse files
committed
Create value class for transactionId. There is no validation on the format, but validation is a bonus for userId, roomId, etc.
The main advantage of using value classes instead of Strings everywhere is to detect errors at compilation time.
1 parent 1e45235 commit 6e2f645

File tree

14 files changed

+59
-22
lines changed

14 files changed

+59
-22
lines changed

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import io.element.android.features.messages.impl.timeline.model.virtual.aTimelin
2727
import io.element.android.libraries.designsystem.components.avatar.AvatarData
2828
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
2929
import io.element.android.libraries.matrix.api.core.EventId
30+
import io.element.android.libraries.matrix.api.core.TransactionId
3031
import io.element.android.libraries.matrix.api.core.UserId
3132
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
3233
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
@@ -101,7 +102,7 @@ fun aTimelineItemDaySeparator(): TimelineItem.Virtual {
101102

102103
internal fun aTimelineItemEvent(
103104
eventId: EventId = EventId("\$" + Random.nextInt().toString()),
104-
transactionId: String? = null,
105+
transactionId: TransactionId? = null,
105106
isMine: Boolean = false,
106107
content: TimelineItemEventContent = aTimelineItemTextContent(),
107108
groupPosition: TimelineItemGroupPosition = TimelineItemGroupPosition.None,

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
2222
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel
2323
import io.element.android.libraries.designsystem.components.avatar.AvatarData
2424
import io.element.android.libraries.matrix.api.core.EventId
25+
import io.element.android.libraries.matrix.api.core.TransactionId
2526
import io.element.android.libraries.matrix.api.core.UserId
2627
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
2728
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
@@ -53,7 +54,7 @@ sealed interface TimelineItem {
5354
data class Event(
5455
val id: String,
5556
val eventId: EventId? = null,
56-
val transactionId: String? = null,
57+
val transactionId: TransactionId? = null,
5758
val senderId: UserId,
5859
val senderDisplayName: String?,
5960
val senderAvatar: AvatarData,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlagService
3737
import io.element.android.libraries.featureflag.api.FeatureFlags
3838
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
3939
import io.element.android.libraries.matrix.api.core.EventId
40+
import io.element.android.libraries.matrix.api.core.TransactionId
4041
import io.element.android.libraries.matrix.api.media.ImageInfo
4142
import io.element.android.libraries.matrix.api.media.VideoInfo
4243
import io.element.android.libraries.matrix.api.room.MatrixRoom
@@ -510,7 +511,7 @@ class MessageComposerPresenterTest {
510511
fun anEditMode(
511512
eventId: EventId? = AN_EVENT_ID,
512513
message: String = A_MESSAGE,
513-
transactionId: String? = null,
514+
transactionId: TransactionId? = null,
514515
) = MessageComposerMode.Edit(eventId, message, transactionId)
515516
fun aReplyMode() = MessageComposerMode.Reply(A_USER_NAME, null, AN_EVENT_ID, A_MESSAGE)
516517
fun aQuoteMode() = MessageComposerMode.Quote(AN_EVENT_ID, A_MESSAGE)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.libraries.matrix.api.core
18+
19+
import java.io.Serializable
20+
21+
@JvmInline
22+
value class TransactionId(val value: String) : Serializable {
23+
override fun toString(): String = value
24+
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.core.EventId
2020
import io.element.android.libraries.matrix.api.core.ProgressCallback
2121
import io.element.android.libraries.matrix.api.core.RoomId
2222
import io.element.android.libraries.matrix.api.core.SessionId
23+
import io.element.android.libraries.matrix.api.core.TransactionId
2324
import io.element.android.libraries.matrix.api.core.UserId
2425
import io.element.android.libraries.matrix.api.media.AudioInfo
2526
import io.element.android.libraries.matrix.api.media.FileInfo
@@ -70,7 +71,7 @@ interface MatrixRoom : Closeable {
7071

7172
suspend fun sendMessage(message: String): Result<Unit>
7273

73-
suspend fun editMessage(originalEventId: EventId?, transactionId: String?, message: String): Result<Unit>
74+
suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, message: String): Result<Unit>
7475

7576
suspend fun replyMessage(eventId: EventId, message: String): Result<Unit>
7677

@@ -88,9 +89,9 @@ interface MatrixRoom : Closeable {
8889

8990
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
9091

91-
suspend fun retrySendMessage(transactionId: String): Result<Unit>
92+
suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit>
9293

93-
suspend fun cancelSend(transactionId: String): Result<Unit>
94+
suspend fun cancelSend(transactionId: TransactionId): Result<Unit>
9495

9596
suspend fun leave(): Result<Unit>
9697

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/MatrixTimelineItem.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
package io.element.android.libraries.matrix.api.timeline
1818

1919
import io.element.android.libraries.matrix.api.core.EventId
20+
import io.element.android.libraries.matrix.api.core.TransactionId
2021
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
2122
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
2223

2324
sealed interface MatrixTimelineItem {
2425
data class Event(val event: EventTimelineItem) : MatrixTimelineItem {
2526
val uniqueId: String = event.uniqueIdentifier
2627
val eventId: EventId? = event.eventId
27-
val transactionId: String? = event.transactionId
28+
val transactionId: TransactionId? = event.transactionId
2829
}
2930

3031
data class Virtual(val virtual: VirtualTimelineItem) : MatrixTimelineItem

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
package io.element.android.libraries.matrix.api.timeline.item.event
1818

1919
import io.element.android.libraries.matrix.api.core.EventId
20+
import io.element.android.libraries.matrix.api.core.TransactionId
2021
import io.element.android.libraries.matrix.api.core.UserId
2122
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
2223

2324
data class EventTimelineItem(
2425
val uniqueIdentifier: String,
2526
val eventId: EventId?,
26-
val transactionId: String?,
27+
val transactionId: TransactionId?,
2728
val isEditable: Boolean,
2829
val isLocal: Boolean,
2930
val isOwn: Boolean,

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.core.EventId
2222
import io.element.android.libraries.matrix.api.core.ProgressCallback
2323
import io.element.android.libraries.matrix.api.core.RoomId
2424
import io.element.android.libraries.matrix.api.core.SessionId
25+
import io.element.android.libraries.matrix.api.core.TransactionId
2526
import io.element.android.libraries.matrix.api.core.UserId
2627
import io.element.android.libraries.matrix.api.media.AudioInfo
2728
import io.element.android.libraries.matrix.api.media.FileInfo
@@ -218,10 +219,10 @@ class RustMatrixRoom(
218219
}
219220
}
220221

221-
override suspend fun editMessage(originalEventId: EventId?, transactionId: String?, message: String): Result<Unit> = withContext(roomDispatcher) {
222+
override suspend fun editMessage(originalEventId: EventId?, transactionId: TransactionId?, message: String): Result<Unit> = withContext(roomDispatcher) {
222223
if (originalEventId != null) {
223224
runCatching {
224-
innerRoom.edit(/* TODO use content */ message, originalEventId.value, transactionId)
225+
innerRoom.edit(/* TODO use content */ message, originalEventId.value, transactionId?.value)
225226
}
226227
} else {
227228
runCatching {
@@ -326,17 +327,17 @@ class RustMatrixRoom(
326327
}
327328
}
328329

329-
override suspend fun retrySendMessage(transactionId: String): Result<Unit> =
330+
override suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit> =
330331
withContext(roomDispatcher) {
331332
runCatching {
332-
innerRoom.retrySend(transactionId)
333+
innerRoom.retrySend(transactionId.value)
333334
}
334335
}
335336

336-
override suspend fun cancelSend(transactionId: String): Result<Unit> =
337+
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> =
337338
withContext(roomDispatcher) {
338339
runCatching {
339-
innerRoom.cancelSend(transactionId)
340+
innerRoom.cancelSend(transactionId.value)
340341
}
341342
}
342343

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.element.android.libraries.matrix.impl.timeline.item.event
1818

1919
import io.element.android.libraries.matrix.api.core.EventId
20+
import io.element.android.libraries.matrix.api.core.TransactionId
2021
import io.element.android.libraries.matrix.api.core.UserId
2122
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
2223
import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
@@ -35,7 +36,7 @@ class EventTimelineItemMapper(private val contentMapper: TimelineEventContentMap
3536
EventTimelineItem(
3637
uniqueIdentifier = it.uniqueIdentifier(),
3738
eventId = it.eventId()?.let(::EventId),
38-
transactionId = it.transactionId(),
39+
transactionId = it.transactionId()?.let(::TransactionId),
3940
isEditable = it.isEditable(),
4041
isLocal = it.isLocal(),
4142
isOwn = it.isOwn(),

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
2222
import io.element.android.libraries.matrix.api.core.SessionId
2323
import io.element.android.libraries.matrix.api.core.SpaceId
2424
import io.element.android.libraries.matrix.api.core.ThreadId
25+
import io.element.android.libraries.matrix.api.core.TransactionId
2526
import io.element.android.libraries.matrix.api.core.UserId
2627

2728
const val A_USER_NAME = "alice"
@@ -37,7 +38,7 @@ val A_ROOM_ID_2 = RoomId("!aRoomId2:domain")
3738
val A_THREAD_ID = ThreadId("\$aThreadId")
3839
val AN_EVENT_ID = EventId("\$anEventId")
3940
val AN_EVENT_ID_2 = EventId("\$anEventId2")
40-
const val A_TRANSACTION_ID = "aTransactionId"
41+
val A_TRANSACTION_ID = TransactionId("aTransactionId")
4142
const val A_UNIQUE_ID = "aUniqueId"
4243

4344
const val A_ROOM_NAME = "A room name"

0 commit comments

Comments
 (0)