mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Fix spaces add room via server
This commit is contained in:
parent
d81d971ce0
commit
1ec08bec07
9 changed files with 91 additions and 50 deletions
|
@ -33,7 +33,7 @@ interface Space {
|
|||
fun spaceSummary(): RoomSummary?
|
||||
|
||||
suspend fun addChildren(roomId: String,
|
||||
viaServers: List<String>,
|
||||
viaServers: List<String>?,
|
||||
order: String?,
|
||||
autoJoin: Boolean = false,
|
||||
suggested: Boolean? = false)
|
||||
|
|
|
@ -18,19 +18,13 @@ package org.matrix.android.sdk.internal.session.permalinks
|
|||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.RoomGetter
|
||||
import java.net.URLEncoder
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
internal class PermalinkFactory @Inject constructor(
|
||||
@UserId
|
||||
private val userId: String,
|
||||
// Use a provider to fix circular Dagger dependency
|
||||
private val roomGetterProvider: Provider<RoomGetter>
|
||||
private val viaParameterFinder: ViaParameterFinder
|
||||
) {
|
||||
|
||||
fun createPermalink(event: Event): String? {
|
||||
|
@ -50,12 +44,12 @@ internal class PermalinkFactory @Inject constructor(
|
|||
return if (roomId.isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
MATRIX_TO_URL_BASE + escape(roomId) + computeViaParams(userId, roomId)
|
||||
MATRIX_TO_URL_BASE + escape(roomId) + viaParameterFinder.computeViaParams(userId, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
fun createPermalink(roomId: String, eventId: String): String {
|
||||
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + computeViaParams(userId, roomId)
|
||||
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + viaParameterFinder.computeViaParams(userId, roomId)
|
||||
}
|
||||
|
||||
fun getLinkedId(url: String): String? {
|
||||
|
@ -66,25 +60,6 @@ internal class PermalinkFactory @Inject constructor(
|
|||
} else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the via parameters.
|
||||
* Take up to 3 homeserver domains, taking the most representative one regarding room members and including the
|
||||
* current user one.
|
||||
*/
|
||||
private fun computeViaParams(userId: String, roomId: String): String {
|
||||
val userHomeserver = userId.substringAfter(":")
|
||||
return getUserIdsOfJoinedMembers(roomId)
|
||||
.map { it.substringAfter(":") }
|
||||
.groupBy { it }
|
||||
.mapValues { it.value.size }
|
||||
.toMutableMap()
|
||||
// Ensure the user homeserver will be included
|
||||
.apply { this[userHomeserver] = Int.MAX_VALUE }
|
||||
.let { map -> map.keys.sortedByDescending { map[it] } }
|
||||
.take(3)
|
||||
.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape '/' in id, because it is used as a separator
|
||||
*
|
||||
|
@ -104,15 +79,4 @@ internal class PermalinkFactory @Inject constructor(
|
|||
private fun unescape(id: String): String {
|
||||
return id.replace("%2F", "/")
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of userIds of joined members of a room
|
||||
*/
|
||||
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
|
||||
return roomGetterProvider.get().getRoom(roomId)
|
||||
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
||||
?.map { it.userId }
|
||||
.orEmpty()
|
||||
.toSet()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.permalinks
|
||||
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.RoomGetter
|
||||
import java.net.URLEncoder
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
internal class ViaParameterFinder @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val roomGetterProvider: Provider<RoomGetter>
|
||||
) {
|
||||
|
||||
fun computeViaParams(roomId: String, max: Int): List<String> {
|
||||
return computeViaParams(userId, roomId, max)
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the via parameters.
|
||||
* Take up to 3 homeserver domains, taking the most representative one regarding room members and including the
|
||||
* current user one.
|
||||
*/
|
||||
fun computeViaParams(userId: String, roomId: String): String {
|
||||
return computeViaParams(userId, roomId, 3)
|
||||
.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
|
||||
}
|
||||
|
||||
fun computeViaParams(userId: String, roomId: String, max: Int): List<String> {
|
||||
val userHomeserver = userId.substringAfter(":")
|
||||
return getUserIdsOfJoinedMembers(roomId)
|
||||
.map { it.substringAfter(":") }
|
||||
.groupBy { it }
|
||||
.mapValues { it.value.size }
|
||||
.toMutableMap()
|
||||
// Ensure the user homeserver will be included
|
||||
.apply { this[userHomeserver] = Int.MAX_VALUE }
|
||||
.let { map -> map.keys.sortedByDescending { map[it] } }
|
||||
.take(max)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of userIds of joined members of a room
|
||||
*/
|
||||
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
|
||||
return roomGetterProvider.get().getRoom(roomId)
|
||||
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
||||
?.map { it.userId }
|
||||
.orEmpty()
|
||||
.toSet()
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.search.SearchResult
|
|||
import org.matrix.android.sdk.api.session.space.Space
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||
import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||
import org.matrix.android.sdk.internal.session.search.SearchTask
|
||||
|
@ -66,6 +67,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
|
|||
private val roomMembersService: MembershipService,
|
||||
private val roomPushRuleService: RoomPushRuleService,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val viaParameterFinder: ViaParameterFinder,
|
||||
private val searchTask: SearchTask) :
|
||||
Room,
|
||||
TimelineService by timelineService,
|
||||
|
@ -154,6 +156,6 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
|
|||
|
||||
override fun asSpace(): Space? {
|
||||
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
||||
return DefaultSpace(this, roomSummaryDataSource)
|
||||
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room
|
|||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.room.Room
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||
import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService
|
||||
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
|
||||
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
|
||||
|
@ -60,6 +61,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
|
|||
private val membershipServiceFactory: DefaultMembershipService.Factory,
|
||||
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val viaParameterFinder: ViaParameterFinder,
|
||||
private val searchTask: SearchTask) :
|
||||
RoomFactory {
|
||||
|
||||
|
@ -83,7 +85,8 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
|
|||
roomMembersService = membershipServiceFactory.create(roomId),
|
||||
roomPushRuleService = roomPushRuleServiceFactory.create(roomId),
|
||||
sendStateTask = sendStateTask,
|
||||
searchTask = searchTask
|
||||
searchTask = searchTask,
|
||||
viaParameterFinder = viaParameterFinder
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@ import org.matrix.android.sdk.api.session.room.Room
|
|||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import org.matrix.android.sdk.api.session.space.Space
|
||||
import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
|
||||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||
|
||||
internal class DefaultSpace(
|
||||
private val room: Room,
|
||||
private val spaceSummaryDataSource: RoomSummaryDataSource
|
||||
private val spaceSummaryDataSource: RoomSummaryDataSource,
|
||||
private val viaParameterFinder: ViaParameterFinder
|
||||
) : Space {
|
||||
|
||||
override fun asRoom(): Room {
|
||||
|
@ -46,15 +48,17 @@ internal class DefaultSpace(
|
|||
}
|
||||
|
||||
override suspend fun addChildren(roomId: String,
|
||||
viaServers: List<String>,
|
||||
viaServers: List<String>?,
|
||||
order: String?,
|
||||
autoJoin: Boolean,
|
||||
suggested: Boolean?) {
|
||||
// Find best via
|
||||
|
||||
room.sendStateEvent(
|
||||
eventType = EventType.STATE_SPACE_CHILD,
|
||||
stateKey = roomId,
|
||||
body = SpaceChildContent(
|
||||
via = viaServers,
|
||||
via = viaServers ?: viaParameterFinder.computeViaParams(roomId, 3),
|
||||
autoJoin = autoJoin,
|
||||
order = order,
|
||||
suggested = suggested
|
||||
|
|
|
@ -832,7 +832,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
session.spaceService().getSpace(spaceId)
|
||||
?.addChildren(
|
||||
state.roomId,
|
||||
listOf(session.sessionParams.homeServerHost ?: ""),
|
||||
null,
|
||||
null,
|
||||
true
|
||||
)
|
||||
|
@ -849,7 +849,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
session.spaceService().getSpace(slashCommandResult.spaceId)
|
||||
?.addChildren(
|
||||
room.roomId,
|
||||
listOf(session.sessionParams.homeServerHost ?: ""),
|
||||
null,
|
||||
null,
|
||||
false
|
||||
)
|
||||
|
|
|
@ -236,10 +236,9 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init
|
|||
if (initialState.parentSpaceId != null) {
|
||||
// add it as a child
|
||||
try {
|
||||
val via = session.sessionParams.homeServerHost?.let { listOf(it) }.orEmpty()
|
||||
session.spaceService()
|
||||
.getSpace(initialState.parentSpaceId)
|
||||
?.addChildren(roomId, viaServers = via, order = null)
|
||||
?.addChildren(roomId, viaServers = null, order = null)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.w(failure, "Failed to add as a child")
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor(
|
|||
try {
|
||||
session.spaceService().getSpace(initialState.spaceId)!!.addChildren(
|
||||
roomId = roomId,
|
||||
viaServers = listOf(session.sessionParams.homeServerHost ?: ""),
|
||||
viaServers = null,
|
||||
order = null
|
||||
)
|
||||
completed.add(roomId)
|
||||
|
|
Loading…
Reference in a new issue