Skip to content

Commit d6b261c

Browse files
authored
Merge pull request #3986 from vector-im/feature/bca/room_summary_api
Better room preview, use room Summary API if available
2 parents c1b14bd + f2b7ee3 commit d6b261c

File tree

6 files changed

+190
-1
lines changed

6 files changed

+190
-1
lines changed

changelog.d/3946.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Restricted Room previews aren't working
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2021 The Matrix.org Foundation C.I.C.
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+
package org.matrix.android.sdk.api.session.room.model
17+
18+
import com.squareup.moshi.Json
19+
import com.squareup.moshi.JsonClass
20+
21+
/**
22+
* These are the same fields as those returned by /publicRooms, with a few additions: room_type, membership and is_encrypted.
23+
*/
24+
@JsonClass(generateAdapter = true)
25+
data class RoomStrippedState(
26+
/**
27+
* Aliases of the room. May be empty.
28+
*/
29+
@Json(name = "aliases")
30+
val aliases: List<String>? = null,
31+
32+
/**
33+
* The canonical alias of the room, if any.
34+
*/
35+
@Json(name = "canonical_alias")
36+
val canonicalAlias: String? = null,
37+
38+
/**
39+
* The name of the room, if any.
40+
*/
41+
@Json(name = "name")
42+
val name: String? = null,
43+
44+
/**
45+
* Required. The number of members joined to the room.
46+
*/
47+
@Json(name = "num_joined_members")
48+
val numJoinedMembers: Int = 0,
49+
50+
/**
51+
* Required. The ID of the room.
52+
*/
53+
@Json(name = "room_id")
54+
val roomId: String,
55+
56+
/**
57+
* The topic of the room, if any.
58+
*/
59+
@Json(name = "topic")
60+
val topic: String? = null,
61+
62+
/**
63+
* Required. Whether the room may be viewed by guest users without joining.
64+
*/
65+
@Json(name = "world_readable")
66+
val worldReadable: Boolean = false,
67+
68+
/**
69+
* Required. Whether guest users may join the room and participate in it. If they can,
70+
* they will be subject to ordinary power level rules like any other user.
71+
*/
72+
@Json(name = "guest_can_join")
73+
val guestCanJoin: Boolean = false,
74+
75+
/**
76+
* The URL for the room's avatar, if one is set.
77+
*/
78+
@Json(name = "avatar_url")
79+
val avatarUrl: String? = null,
80+
81+
/**
82+
* Undocumented item
83+
*/
84+
@Json(name = "m.federate")
85+
val isFederated: Boolean = false,
86+
87+
/**
88+
* Optional. If the room is encrypted. This is already accessible as stripped state.
89+
*/
90+
@Json(name = "is_encrypted")
91+
val isEncrypted: Boolean?,
92+
93+
/**
94+
* Optional. Type of the room, if any, i.e. m.space
95+
*/
96+
@Json(name = "room_type")
97+
val roomType: String?,
98+
99+
/**
100+
* The current membership of this user in the room. Usually leave if the room is fetched over federation.
101+
*/
102+
@Json(name = "membership")
103+
val membership: String?
104+
) {
105+
/**
106+
* Return the canonical alias, or the first alias from the list of aliases, or null
107+
*/
108+
fun getPrimaryAlias(): String? {
109+
return canonicalAlias ?: aliases?.firstOrNull()
110+
}
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2021 The Matrix.org Foundation C.I.C.
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 org.matrix.android.sdk.internal.session.room
18+
19+
import org.matrix.android.sdk.api.session.room.model.RoomStrippedState
20+
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
21+
import org.matrix.android.sdk.internal.network.executeRequest
22+
import org.matrix.android.sdk.internal.task.Task
23+
import javax.inject.Inject
24+
25+
internal interface GetRoomSummaryTask : Task<GetRoomSummaryTask.Params, RoomStrippedState> {
26+
data class Params(
27+
val roomId: String,
28+
val viaServers: List<String>?
29+
)
30+
}
31+
32+
internal class DefaultGetRoomSummaryTask @Inject constructor(
33+
private val roomAPI: RoomAPI,
34+
private val globalErrorReceiver: GlobalErrorReceiver
35+
) : GetRoomSummaryTask {
36+
37+
override suspend fun execute(params: GetRoomSummaryTask.Params): RoomStrippedState {
38+
return executeRequest(globalErrorReceiver) {
39+
roomAPI.getRoomSummary(params.roomId, params.viaServers)
40+
}
41+
}
42+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt

+12-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room
1919
import org.matrix.android.sdk.api.session.events.model.Content
2020
import org.matrix.android.sdk.api.session.events.model.Event
2121
import org.matrix.android.sdk.api.session.room.model.Membership
22+
import org.matrix.android.sdk.api.session.room.model.RoomStrippedState
2223
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
2324
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
2425
import org.matrix.android.sdk.api.util.JsonDict
@@ -254,7 +255,7 @@ internal interface RoomAPI {
254255
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "join/{roomIdOrAlias}")
255256
suspend fun join(@Path("roomIdOrAlias") roomIdOrAlias: String,
256257
@Query("server_name") viaServers: List<String>,
257-
@Body params: JsonDict): JoinRoomResponse
258+
@Body params: JsonDict): JoinRoomResponse
258259

259260
/**
260261
* Leave the given room.
@@ -381,4 +382,14 @@ internal interface RoomAPI {
381382
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/upgrade")
382383
suspend fun upgradeRoom(@Path("roomId") roomId: String,
383384
@Body body: RoomUpgradeBody): RoomUpgradeResponse
385+
386+
/**
387+
* The API returns the summary of the specified room, if the room could be found and the client should be able to view
388+
* its contents according to the join_rules, history visibility, space membership and similar rules outlined in MSC3173
389+
* as well as if the user is already a member of that room.
390+
* https://github.com/deepbluev7/matrix-doc/blob/room-summaries/proposals/3266-room-summary.md
391+
*/
392+
@GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "im.nheko.summary/rooms/{roomIdOrAlias}/summary")
393+
suspend fun getRoomSummary(@Path("roomIdOrAlias") roomidOrAlias: String,
394+
@Query("via") viaServers: List<String>?): RoomStrippedState
384395
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt

+3
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,7 @@ internal abstract class RoomModule {
253253

254254
@Binds
255255
abstract fun bindSign3pidInvitationTask(task: DefaultSign3pidInvitationTask): Sign3pidInvitationTask
256+
257+
@Binds
258+
abstract fun bindGetRoomSummaryTask(task: DefaultGetRoomSummaryTask): GetRoomSummaryTask
256259
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt

+21
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsFi
3333
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
3434
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
3535
import org.matrix.android.sdk.api.util.MatrixItem
36+
import org.matrix.android.sdk.internal.session.room.GetRoomSummaryTask
3637
import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask
3738
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
3839
import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
@@ -49,6 +50,7 @@ internal class DefaultPeekRoomTask @Inject constructor(
4950
private val getRoomIdByAliasTask: GetRoomIdByAliasTask,
5051
private val getRoomDirectoryVisibilityTask: GetRoomDirectoryVisibilityTask,
5152
private val getPublicRoomTask: GetPublicRoomTask,
53+
private val getRoomSummaryTask: GetRoomSummaryTask,
5254
private val resolveRoomStateTask: ResolveRoomStateTask
5355
) : PeekRoomTask {
5456

@@ -70,6 +72,25 @@ internal class DefaultPeekRoomTask @Inject constructor(
7072
serverList = emptyList()
7173
}
7274

75+
// If the room summary API is available on the Home Server we should try it first
76+
val strippedState = tryOrNull("Failed to get room stripped state roomId:$roomId") {
77+
getRoomSummaryTask.execute(GetRoomSummaryTask.Params(roomId, serverList))
78+
}
79+
if (strippedState != null) {
80+
return PeekResult.Success(
81+
roomId = strippedState.roomId,
82+
alias = strippedState.getPrimaryAlias() ?: params.roomIdOrAlias.takeIf { isAlias },
83+
avatarUrl = strippedState.avatarUrl,
84+
name = strippedState.name,
85+
topic = strippedState.topic,
86+
numJoinedMembers = strippedState.numJoinedMembers,
87+
viaServers = serverList,
88+
roomType = strippedState.roomType,
89+
someMembers = null,
90+
isPublic = strippedState.worldReadable
91+
)
92+
}
93+
7394
// Is it a public room?
7495
val visibilityRes = tryOrNull("## PEEK: failed to get visibility") {
7596
getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))

0 commit comments

Comments
 (0)