From a4c84879d17667adb7e3eab22c532dbed14846ea Mon Sep 17 00:00:00 2001 From: Eneko Nieto Date: Mon, 18 Apr 2022 00:34:59 +0200 Subject: [PATCH] joinTravel() finished --- .../TravelEventContentSerializerMappings.kt | 4 +-- .../TravelCreatedMessageEventContent.kt | 2 +- ...tent.kt => MembershipStateEventContent.kt} | 2 +- .../state/TravelCreatedStateEventContent.kt | 2 +- .../okupamicoche/matrix/matrixApiClient.kt | 23 ++++++++++++-- .../usecase/travel/createTravel.kt | 10 ++++++ .../okupamicoche/usecase/travel/joinTravel.kt | 31 ++++++++++++++++--- 7 files changed, 62 insertions(+), 12 deletions(-) rename src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/{MembershipChangeStateEventContent.kt => MembershipStateEventContent.kt} (93%) diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt index eee6479..9230436 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelEventContentSerializerMappings.kt @@ -5,7 +5,7 @@ import eu.fosil.okupamicoche.matrix.event.message.JoinMessageEventContent import eu.fosil.okupamicoche.matrix.event.message.TRAVEL_CREATED_MESSAGE_EVENT_TYPE import eu.fosil.okupamicoche.matrix.event.message.TravelCreatedMessageEventContent import eu.fosil.okupamicoche.matrix.event.state.MEMBERSHIP_CHANGE_STATE_EVENT_TYPE -import eu.fosil.okupamicoche.matrix.event.state.MembershipChangeStateEventContent +import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent import eu.fosil.okupamicoche.matrix.event.state.TRAVEL_CREATED_STATE_EVENT_TYPE import eu.fosil.okupamicoche.matrix.event.state.TravelCreatedStateEventContent import net.folivo.trixnity.core.model.events.MessageEventContent @@ -20,6 +20,6 @@ object TravelEventContentSerializerMappings : BaseEventContentSerializerMappings ) override val state: Set> = setOf( EventContentSerializerMapping.of(TRAVEL_CREATED_STATE_EVENT_TYPE), - EventContentSerializerMapping.of(MEMBERSHIP_CHANGE_STATE_EVENT_TYPE) + EventContentSerializerMapping.of(MEMBERSHIP_CHANGE_STATE_EVENT_TYPE) ) } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/message/TravelCreatedMessageEventContent.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/message/TravelCreatedMessageEventContent.kt index 002c0df..f3418b8 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/message/TravelCreatedMessageEventContent.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/message/TravelCreatedMessageEventContent.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable import net.folivo.trixnity.core.model.events.MessageEventContent import net.folivo.trixnity.core.model.events.RelatesTo -const val TRAVEL_CREATED_MESSAGE_EVENT_TYPE = "eu.fosil.travel.created.message" +const val TRAVEL_CREATED_MESSAGE_EVENT_TYPE = "eu.fosil.travel.created" @Serializable data class TravelCreatedMessageEventContent( diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipChangeStateEventContent.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipStateEventContent.kt similarity index 93% rename from src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipChangeStateEventContent.kt rename to src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipStateEventContent.kt index f135b1d..5b6d469 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipChangeStateEventContent.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/MembershipStateEventContent.kt @@ -9,7 +9,7 @@ import net.folivo.trixnity.core.model.events.m.room.Membership const val MEMBERSHIP_CHANGE_STATE_EVENT_TYPE = "eu.fosil.travel.member" @Serializable -data class MembershipChangeStateEventContent( +data class MembershipStateEventContent( @SerialName("user") val user: String, @SerialName("membership") diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/TravelCreatedStateEventContent.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/TravelCreatedStateEventContent.kt index 74e45a5..a234a0f 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/TravelCreatedStateEventContent.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/state/TravelCreatedStateEventContent.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable import net.folivo.trixnity.core.model.UserId import net.folivo.trixnity.core.model.events.StateEventContent -const val TRAVEL_CREATED_STATE_EVENT_TYPE = "eu.fosil.travel.created.state" +const val TRAVEL_CREATED_STATE_EVENT_TYPE = "eu.fosil.travel.created" @Serializable data class TravelCreatedStateEventContent( diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt index d1f0c5f..c24abbd 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt @@ -2,9 +2,12 @@ package eu.fosil.okupamicoche.matrix import eu.fosil.okupamicoche.config.ConfigReader import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings +import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent +import eu.fosil.okupamicoche.matrix.event.state.TravelCreatedStateEventContent import io.ktor.http.* import mu.KotlinLogging import net.folivo.trixnity.clientserverapi.client.MatrixClientServerApiClient +import net.folivo.trixnity.clientserverapi.client.getStateEvent import net.folivo.trixnity.clientserverapi.model.rooms.DirectoryVisibility import net.folivo.trixnity.core.model.RoomAliasId import net.folivo.trixnity.core.model.RoomId @@ -36,6 +39,22 @@ object MatrixApiClient { suspend fun getDisplayName(userId: UserId) = matrixApiClient?.users?.getDisplayName(userId)?.getOrNull() ?: userId.localpart + suspend fun isTravel(roomId: RoomId) = + matrixApiClient?.rooms?.getStateEvent( + roomId + )?.getOrNull() !== null + + suspend fun isDriver(roomId: RoomId, userId: UserId) = + matrixApiClient?.rooms?.getStateEvent( + roomId + )?.getOrNull()?.driver == userId.full + + suspend fun getTravelMembership(roomId: RoomId, userId: UserId) = + matrixApiClient?.rooms?.getStateEvent( + roomId, + userId.full.substring(1) // Synapse throws 403 if stateKey starts with '@' + )?.getOrNull()?.membership + private suspend fun createMainRoomIfNeeded(): RoomId? { requireNotNull(config) requireNotNull(matrixApiClient) @@ -52,9 +71,9 @@ object MatrixApiClient { ).getOrNull() } else { mainRoomId = roomAliasRes.roomId - val joinedToMainRoom = (matrixApiClient.rooms.getJoinedRooms().getOrNull()?.filter { roomId -> + val joinedToMainRoom = (matrixApiClient.rooms.getJoinedRooms().getOrNull()?.firstOrNull { roomId -> roomId == mainRoomId - }?.firstOrNull()) !== null + }) !== null logger.info("alreadyJoinedToMainRoom=$joinedToMainRoom") if (!joinedToMainRoom) { diff --git a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt index dd3b3a4..10c7204 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt @@ -74,10 +74,20 @@ private suspend fun createRoom(travelOptions: TravelOptions, driver: UserId): Ro name = newRoomAliasAndName.name, topic = travelOptions.description, invite = setOf(driver), + roomVersion = "9", // TODO: uncomment when https://gitlab.com/benkuly/trixnity/-/issues/119 gets fixed // initialState = listOf(initialState), powerLevelContentOverride = powerLevels ).getOrThrow() + +// NOT IMPLEMENTED IN ELEMENT YET +// https://github.com/vector-im/element-android/issues/3875 +// https://github.com/vector-im/element-web/issues/18655 +// Send joining rule state event +// matrixApiClient.rooms.sendStateEvent( +// roomId, +// JoinRulesEventContent(JoinRulesEventContent.JoinRule.Knock) +// ) } private suspend fun getRoomAliasAndName(travelOptions: TravelOptions): RoomAliasAndName { diff --git a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/joinTravel.kt b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/joinTravel.kt index 1711391..56c79c5 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/joinTravel.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/joinTravel.kt @@ -1,7 +1,7 @@ package eu.fosil.okupamicoche.usecase.travel import eu.fosil.okupamicoche.matrix.MatrixApiClient -import eu.fosil.okupamicoche.matrix.event.state.MembershipChangeStateEventContent +import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent import eu.fosil.okupamicoche.matrix.matrixApiClient import net.folivo.trixnity.core.model.RoomId import net.folivo.trixnity.core.model.UserId @@ -12,11 +12,32 @@ suspend fun joinTravel( roomId: RoomId, userId: UserId ) { + requireNotNull(matrixApiClient) + val isTravel = MatrixApiClient.isTravel(roomId) + val isDriver = MatrixApiClient.isDriver(roomId, userId) + val membershipState = MatrixApiClient.getTravelMembership(roomId, userId) - sendJoinMessageEvents(roomId, userId) + if (!isTravel) { + sendErrorTextMessage(roomId, "There is no travel.") + } else if (isDriver) { + sendErrorTextMessage(roomId, "You are the driver, you don't need to join.") + } else if (membershipState == Membership.JOIN.value) { + sendErrorTextMessage(roomId, "You were already joined.") + } else { + sendJoinedMessageEvents(roomId, userId) + } } -private suspend fun sendJoinMessageEvents( +private suspend fun sendErrorTextMessage(roomId: RoomId, messageBody: String) { + requireNotNull(matrixApiClient) + + matrixApiClient.rooms.sendMessageEvent( + roomId, + RoomMessageEventContent.TextMessageEventContent(messageBody) + ) +} + +private suspend fun sendJoinedMessageEvents( roomId: RoomId, userId: UserId ) { @@ -24,7 +45,7 @@ private suspend fun sendJoinMessageEvents( // Send text message to travel room val displayName = MatrixApiClient.getDisplayName(userId) - val messageBody = "$displayName joined the travel!" + val messageBody = "$displayName joined the travel." matrixApiClient.rooms.sendMessageEvent( roomId, RoomMessageEventContent.TextMessageEventContent(messageBody) @@ -33,7 +54,7 @@ private suspend fun sendJoinMessageEvents( // Send membership change state event to travel room matrixApiClient.rooms.sendStateEvent( roomId, - MembershipChangeStateEventContent(userId, Membership.JOIN), + MembershipStateEventContent(userId, Membership.JOIN), stateKey = userId.full.substring(1) // Synapse throws 403 if stateKey starts with '@' ).getOrThrow()