From bd9da8eaa6dddf74e23f678e01539c01955d462b Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 11 Dec 2020 15:06:22 +0100 Subject: [PATCH 1/5] element:// support + basic peeking + fix join via server --- .../org/matrix/android/sdk/rx/RxSession.kt | 3 +- .../session/permalinks/PermalinkService.kt | 1 + .../sdk/api/session/room/RoomService.kt | 14 +- .../session/room/DefaultRoomService.kt | 25 ++- .../sdk/internal/session/room/RoomAPI.kt | 3 + .../sdk/internal/session/room/RoomModule.kt | 10 + .../room/alias/GetRoomIdByAliasTask.kt | 14 +- .../room/alias/RoomAliasDescription.kt | 2 +- .../session/room/peeking/PeekRoomTask.kt | 173 ++++++++++++++++++ .../room/peeking/ResolveRoomStateTask.kt | 42 +++++ vector/src/main/AndroidManifest.xml | 5 + .../vector/app/features/home/HomeActivity.kt | 34 +++- .../features/permalink/PermalinkHandler.kt | 41 +++-- .../app/features/popup/PopupAlertManager.kt | 2 +- .../roompreview/RoomPreviewActivity.kt | 1 + .../RoomPreviewNoPreviewFragment.kt | 76 ++++++-- .../roompreview/RoomPreviewViewModel.kt | 56 +++++- .../roompreview/RoomPreviewViewState.kt | 28 ++- .../fragment_room_preview_no_preview.xml | 10 +- vector/src/main/res/values/strings.xml | 3 +- 20 files changed, 488 insertions(+), 55 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt index 0e5b88adb2..a7b269fcc6 100644 --- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt @@ -47,6 +47,7 @@ import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo +import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription class RxSession(private val session: Session) { @@ -139,7 +140,7 @@ class RxSession(private val session: Session) { } fun getRoomIdByAlias(roomAlias: String, - searchOnServer: Boolean): Single> = singleBuilder { + searchOnServer: Boolean): Single> = singleBuilder { session.getRoomIdByAlias(roomAlias, searchOnServer, it) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index ac1d726d03..aefc086b43 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -25,6 +25,7 @@ interface PermalinkService { companion object { const val MATRIX_TO_URL_BASE = "https://matrix.to/#/" + const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index 477bef66cf..441a64e2c0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -18,12 +18,15 @@ package org.matrix.android.sdk.api.session.room import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription +import org.matrix.android.sdk.internal.session.room.peeking.PeekResult /** * This interface defines methods to get rooms. It's implemented at the session level. @@ -120,7 +123,7 @@ interface RoomService { */ fun getRoomIdByAlias(roomAlias: String, searchOnServer: Boolean, - callback: MatrixCallback>): Cancelable + callback: MatrixCallback>): Cancelable /** * Delete a room alias @@ -163,4 +166,13 @@ interface RoomService { * @return a LiveData of the optional found room member */ fun getRoomMemberLive(userId: String, roomId: String): LiveData> + + fun getRoomState(roomId: String, callback: MatrixCallback>) + + /** + * Use this if you want to get information from a room that you are not yet in (or invited) + * It might be possible to get some information on this room if it is public or if guest access is allowed + * This call will try to gather some information on this room, but it could fail and get nothing more + */ + fun peekRoom(roomIdOrAlias: String, callback: MatrixCallback) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index 9ec985e0b6..e540105800 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -20,6 +20,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.RoomService import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams @@ -35,10 +36,14 @@ import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFie import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.alias.DeleteRoomAliasTask import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask +import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomTask +import org.matrix.android.sdk.internal.session.room.peeking.PeekResult +import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask +import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateBreadcrumbsTask @@ -55,6 +60,8 @@ internal class DefaultRoomService @Inject constructor( private val updateBreadcrumbsTask: UpdateBreadcrumbsTask, private val roomIdByAliasTask: GetRoomIdByAliasTask, private val deleteRoomAliasTask: DeleteRoomAliasTask, + private val resolveRoomStateTask: ResolveRoomStateTask, + private val peekRoomTask: PeekRoomTask, private val roomGetter: RoomGetter, private val roomSummaryDataSource: RoomSummaryDataSource, private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource, @@ -119,7 +126,7 @@ internal class DefaultRoomService @Inject constructor( .executeBy(taskExecutor) } - override fun getRoomIdByAlias(roomAlias: String, searchOnServer: Boolean, callback: MatrixCallback>): Cancelable { + override fun getRoomIdByAlias(roomAlias: String, searchOnServer: Boolean, callback: MatrixCallback>): Cancelable { return roomIdByAliasTask .configureWith(GetRoomIdByAliasTask.Params(roomAlias, searchOnServer)) { this.callback = callback @@ -154,4 +161,20 @@ internal class DefaultRoomService @Inject constructor( results.firstOrNull().toOptional() } } + + override fun getRoomState(roomId: String, callback: MatrixCallback>) { + resolveRoomStateTask + .configureWith(ResolveRoomStateTask.Params(roomId)) { + this.callback = callback + } + .executeBy(taskExecutor) + } + + override fun peekRoom(roomIdOrAlias: String, callback: MatrixCallback) { + peekRoomTask + .configureWith(PeekRoomTask.Params(roomIdOrAlias)) { + this.callback = callback + } + .executeBy(taskExecutor) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 955a251b52..f335987085 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -354,4 +354,7 @@ internal interface RoomAPI { fun deleteTag(@Path("userId") userId: String, @Path("roomId") roomId: String, @Path("tag") tag: String): Call + + @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state") + fun getRoomState(@Path("roomId") roomId: String) : Call> } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt index 3a94396a61..92f4ea2aea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt @@ -57,6 +57,10 @@ import org.matrix.android.sdk.internal.session.room.membership.leaving.DefaultLe import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoomTask import org.matrix.android.sdk.internal.session.room.membership.threepid.DefaultInviteThreePidTask import org.matrix.android.sdk.internal.session.room.membership.threepid.InviteThreePidTask +import org.matrix.android.sdk.internal.session.room.peeking.DefaultPeekRoomTask +import org.matrix.android.sdk.internal.session.room.peeking.DefaultResolveRoomStateTask +import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask +import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.read.DefaultMarkAllRoomsReadTask import org.matrix.android.sdk.internal.session.room.read.DefaultSetReadMarkersTask import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask @@ -223,4 +227,10 @@ internal abstract class RoomModule { @Binds abstract fun bindDeleteTagFromRoomTask(task: DefaultDeleteTagFromRoomTask): DeleteTagFromRoomTask + + @Binds + abstract fun bindResolveRoomStateTask(task: DefaultResolveRoomStateTask): ResolveRoomStateTask + + @Binds + abstract fun bindPeekRoomTask(task: DefaultPeekRoomTask): PeekRoomTask } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt index 3c47ee6ef0..2fe290ead2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt @@ -29,7 +29,7 @@ import org.matrix.android.sdk.internal.session.directory.DirectoryAPI import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject -internal interface GetRoomIdByAliasTask : Task> { +internal interface GetRoomIdByAliasTask : Task> { data class Params( val roomAlias: String, val searchOnServer: Boolean @@ -42,21 +42,21 @@ internal class DefaultGetRoomIdByAliasTask @Inject constructor( private val eventBus: EventBus ) : GetRoomIdByAliasTask { - override suspend fun execute(params: GetRoomIdByAliasTask.Params): Optional { + override suspend fun execute(params: GetRoomIdByAliasTask.Params): Optional { var roomId = Realm.getInstance(monarchy.realmConfiguration).use { RoomSummaryEntity.findByAlias(it, params.roomAlias)?.roomId } return if (roomId != null) { - Optional.from(roomId) + Optional.from(RoomAliasDescription(roomId)) } else if (!params.searchOnServer) { - Optional.from(null) + Optional.from(null) } else { - roomId = tryOrNull("## Failed to get roomId from alias") { + val description = tryOrNull("## Failed to get roomId from alias") { executeRequest(eventBus) { apiCall = directoryAPI.getRoomIdByAlias(params.roomAlias) } - }?.roomId - Optional.from(roomId) + } + Optional.from(description) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt index ada3839fa0..d1f93c50be 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt @@ -20,7 +20,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class RoomAliasDescription( +data class RoomAliasDescription( /** * The room ID for this alias. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt new file mode 100644 index 0000000000..ae557adb5f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * 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.room.peeking + +import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent +import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent +import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility +import org.matrix.android.sdk.api.session.room.model.RoomNameContent +import org.matrix.android.sdk.api.session.room.model.RoomTopicContent +import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsFilter +import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams +import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask +import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask +import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask +import org.matrix.android.sdk.internal.task.Task +import javax.inject.Inject + +sealed class PeekResult { + data class Success( + val roomId: String, + val alias: String?, + val name: String?, + val topic: String?, + val avatarUrl: String?, + val numJoinedMembers: Int?, + val viaServers: List + ) : PeekResult() + + data class PeekingNotAllowed( + val roomId: String, + val alias: String?, + val viaServers: List + ) : PeekResult() + + object UnknownAlias : PeekResult() +} + +internal interface PeekRoomTask : Task { + data class Params( + val roomIdOrAlias: String + ) +} + +internal class DefaultPeekRoomTask @Inject constructor( + private val getRoomIdByAliasTask: GetRoomIdByAliasTask, + private val getRoomDirectoryVisibilityTask: GetRoomDirectoryVisibilityTask, + private val getPublicRoomTask: GetPublicRoomTask, + private val resolveRoomStateTask: ResolveRoomStateTask +) : PeekRoomTask { + + override suspend fun execute(params: PeekRoomTask.Params): PeekResult { + val roomId: String? + val serverList: List + val isAlias: Boolean + if (MatrixPatterns.isRoomAlias(params.roomIdOrAlias)) { + isAlias = true + // get alias description + val aliasDescription = getRoomIdByAliasTask + .execute(GetRoomIdByAliasTask.Params(params.roomIdOrAlias, true)) + .getOrNull() + ?: return PeekResult.UnknownAlias + + roomId = aliasDescription.roomId + serverList = aliasDescription.servers + } else { + isAlias = false + roomId = params.roomIdOrAlias + serverList = emptyList() + } + + // Is it a public room? + val publicRepoResult = when (getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))) { + RoomDirectoryVisibility.PRIVATE -> { + // We cannot resolve this room :/ + null + } + RoomDirectoryVisibility.PUBLIC -> { + // Try to find it in directory + val filter = if (isAlias) PublicRoomsFilter(searchTerm = params.roomIdOrAlias.substring(1)) + else null + + getPublicRoomTask.execute(GetPublicRoomTask.Params( + server = serverList.firstOrNull(), + publicRoomsParams = PublicRoomsParams( + filter = filter, + limit = 20.takeIf { filter != null } ?: 100 + ) + )).chunk?.firstOrNull { it.roomId == roomId } + } + } + + if (publicRepoResult != null) { + return PeekResult.Success( + roomId = roomId, + alias = publicRepoResult.getPrimaryAlias() ?: params.roomIdOrAlias.takeIf { isAlias }, + avatarUrl = publicRepoResult.avatarUrl, + name = publicRepoResult.name, + topic = publicRepoResult.topic, + numJoinedMembers = publicRepoResult.numJoinedMembers, + viaServers = serverList + ) + } + + // mm... try to peek state ? maybe the room is not public but yet allow guest to get events? + // this could be slow + try { + val stateEvents = resolveRoomStateTask + .execute(ResolveRoomStateTask.Params(roomId)) + val name = stateEvents.lastOrNull { + it.type == EventType.STATE_ROOM_NAME + && it.stateKey == "" + }?.let { it.content?.toModel()?.name } + + val topic = stateEvents.lastOrNull { + it.type == EventType.STATE_ROOM_TOPIC + && it.stateKey == "" + }?.let { it.content?.toModel()?.topic } + + val avatarUrl = stateEvents.lastOrNull { + it.type == EventType.STATE_ROOM_AVATAR + }?.let { it.content?.toModel()?.avatarUrl } + + val alias = stateEvents.lastOrNull { + it.type == EventType.STATE_ROOM_CANONICAL_ALIAS + }?.let { + it.content?.toModel()?.canonicalAlias + ?: it.content?.toModel()?.alternativeAliases?.firstOrNull() + } + + // not sure if it's the right way to do that :/ + val memberCount = stateEvents.filter { + it.type == EventType.STATE_ROOM_MEMBER + && it.stateKey?.isNotEmpty() == true + }.distinctBy { it.stateKey } + .count() + + return PeekResult.Success( + roomId = roomId, + alias = alias, + avatarUrl = avatarUrl, + name = name, + topic = topic, + numJoinedMembers = memberCount, + viaServers = serverList + ) + } catch (failure: Throwable) { + // Would be M_FORBIDDEN if cannot peek :/ + // User XXX not in room !XXX, and room previews are disabled + return PeekResult.PeekingNotAllowed( + roomId = roomId, + alias = params.roomIdOrAlias.takeIf { isAlias }, + viaServers = serverList + ) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt new file mode 100644 index 0000000000..289fdb498f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * 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.room.peeking + +import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.internal.network.executeRequest +import org.matrix.android.sdk.internal.session.room.RoomAPI +import org.matrix.android.sdk.internal.task.Task +import javax.inject.Inject + +internal interface ResolveRoomStateTask : Task> { + data class Params( + val roomId: String + ) +} + +internal class DefaultResolveRoomStateTask @Inject constructor( + private val roomAPI: RoomAPI, + private val eventBus: EventBus +) : ResolveRoomStateTask { + + override suspend fun execute(params: ResolveRoomStateTask.Params): List { + return executeRequest(eventBus) { + apiCall = roomAPI.getRoomState(params.roomId) + } + } +} diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index e9bd03cb4b..fc3c7366ec 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -199,6 +199,11 @@ + + + diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 7dde0edf32..4ec786f841 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -126,9 +126,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet .observe() .subscribe { sharedAction -> when (sharedAction) { - is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) + is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START) - is HomeActivitySharedAction.OpenGroup -> { + is HomeActivitySharedAction.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) } @@ -145,9 +145,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet homeActivityViewModel.observeViewEvents { when (it) { is HomeActivityViewEvents.AskPasswordToInitCrossSigning -> handleAskPasswordToInitCrossSigning(it) - is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) - HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() - is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) + is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) + HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() + is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) }.exhaustive } homeActivityViewModel.subscribe(this) { renderState(it) } @@ -162,9 +162,27 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet private fun handleIntent(intent: Intent?) { intent?.dataString?.let { deepLink -> - if (!deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE)) return@let + val resolvedLink = if (deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { + deepLink + } else if (deepLink.startsWith(PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE)) { + // This is a bit hugly, but for now just convert to matrix.to link for compatibility + val service = activeSessionHolder.getSafeActiveSession()?.permalinkService() + val roomLinkPrefix = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" + val userPrefix = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" + when { + deepLink.startsWith(userPrefix) -> { + val userId = deepLink.substring(userPrefix.length) + service?.createPermalink(userId) + } + deepLink.startsWith(roomLinkPrefix) -> { + val param = deepLink.substring(roomLinkPrefix.length) + service?.createRoomPermalink(param) + } + else -> null + } + } else null - permalinkHandler.launch(this, deepLink, + permalinkHandler.launch(this, resolvedLink, navigationInterceptor = this, buildTask = true) // .delay(500, TimeUnit.MILLISECONDS) @@ -180,7 +198,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet private fun renderState(state: HomeActivityViewState) { when (val status = state.initialSyncProgressServiceStatus) { - is InitialSyncProgressService.Status.Idle -> { + is InitialSyncProgressService.Status.Idle -> { waiting_view.isVisible = false } is InitialSyncProgressService.Status.Progressing -> { diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index f1149d8990..4e8b73cb2b 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -31,6 +31,7 @@ import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.rx.rx import javax.inject.Inject @@ -76,7 +77,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti buildTask: Boolean ): Single { return when (permalinkData) { - is PermalinkData.RoomLink -> { + is PermalinkData.RoomLink -> { permalinkData.getRoomId() .observeOn(AndroidSchedulers.mainThread()) .map { @@ -92,11 +93,11 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti true } } - is PermalinkData.GroupLink -> { + is PermalinkData.GroupLink -> { navigator.openGroupDetail(permalinkData.groupId, context, buildTask) Single.just(true) } - is PermalinkData.UserLink -> { + is PermalinkData.UserLink -> { if (navigationInterceptor?.navToMemberProfile(permalinkData.userId, rawLink) != true) { navigator.openRoomMemberProfile(userId = permalinkData.userId, roomId = null, context = context, buildTask = buildTask) } @@ -111,7 +112,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti private fun PermalinkData.RoomLink.getRoomId(): Single> { val session = activeSessionHolder.getSafeActiveSession() return if (isRoomAlias && session != null) { - session.rx().getRoomIdByAlias(roomIdOrAlias, true).subscribeOn(Schedulers.io()) + session.rx().getRoomIdByAlias(roomIdOrAlias, true).map { it.getOrNull()?.roomId.toOptional() }.subscribeOn(Schedulers.io()) } else { Single.just(Optional.from(roomIdOrAlias)) } @@ -149,16 +150,28 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigator.openRoom(context, roomId, eventId, buildTask) } else -> { - val roomPreviewData = RoomPreviewData( - roomId = roomId, - eventId = eventId, - roomAlias = roomAlias ?: roomSummary?.canonicalAlias, - roomName = roomSummary?.displayName, - avatarUrl = roomSummary?.avatarUrl, - buildTask = buildTask, - homeServers = permalinkData.viaParameters - ) - navigator.openRoomPreview(context, roomPreviewData) + if (roomSummary == null) { + // we don't know this room, try to peek + val roomPreviewData = RoomPreviewData( + roomId = roomId, + roomAlias = roomAlias, + peekFromServer = true, + buildTask = buildTask, + homeServers = permalinkData.viaParameters + ) + navigator.openRoomPreview(context, roomPreviewData) + } else { + val roomPreviewData = RoomPreviewData( + roomId = roomId, + eventId = eventId, + roomAlias = roomAlias ?: roomSummary.canonicalAlias, + roomName = roomSummary.displayName, + avatarUrl = roomSummary.avatarUrl, + buildTask = buildTask, + homeServers = permalinkData.viaParameters + ) + navigator.openRoomPreview(context, roomPreviewData) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt index b2257b250a..c677a99175 100644 --- a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt +++ b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt @@ -130,7 +130,7 @@ class PopupAlertManager @Inject constructor(private val avatarRenderer: Lazy = emptyList(), + val peekFromServer: Boolean = false, val buildTask: Boolean = false ) : Parcelable { val matrixItem: MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index 108c3bacf1..bc4552fc11 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -20,6 +20,8 @@ import android.os.Bundle import android.view.View import androidx.core.view.isVisible import androidx.transition.TransitionManager +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.Success import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -30,6 +32,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomdirectory.JoinState import kotlinx.android.synthetic.main.fragment_room_preview_no_preview.* +import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject /** @@ -48,22 +51,6 @@ class RoomPreviewNoPreviewFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupToolbar(roomPreviewNoPreviewToolbar) - val titleText = roomPreviewData.roomName ?: roomPreviewData.roomAlias ?: roomPreviewData.roomId - - // Toolbar - avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewToolbarAvatar) - roomPreviewNoPreviewToolbarTitle.text = titleText - - // Screen - avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewAvatar) - roomPreviewNoPreviewName.text = titleText - roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic) - - if (roomPreviewData.worldReadable) { - roomPreviewNoPreviewLabel.setText(R.string.room_preview_world_readable_room_not_supported_yet) - } else { - roomPreviewNoPreviewLabel.setText(R.string.room_preview_no_preview) - } roomPreviewNoPreviewJoin.callback = object : ButtonStateView.Callback { override fun onButtonClicked() { @@ -100,7 +87,62 @@ class RoomPreviewNoPreviewFragment @Inject constructor( // Quit this screen requireActivity().finish() // Open room - navigator.openRoom(requireActivity(), roomPreviewData.roomId, roomPreviewData.eventId, roomPreviewData.buildTask) + navigator.openRoom(requireActivity(), state.roomId, roomPreviewData.eventId, roomPreviewData.buildTask) + } + + val bestName = state.roomName ?: state.roomAlias ?: state.roomId + when (state.peekingState) { + is Loading -> { + roomPreviewPeekingProgress.isVisible = true + roomPreviewNoPreviewJoin.isVisible = false + } + is Success -> { + roomPreviewPeekingProgress.isVisible = false + when (state.peekingState.invoke()) { + PeekingState.FOUND -> { + // show join buttons + roomPreviewNoPreviewJoin.isVisible = true + renderState(bestName, state.matrixItem(), state.roomTopic) + } + PeekingState.NO_ACCESS -> { + roomPreviewNoPreviewJoin.isVisible = true + roomPreviewNoPreviewLabel.isVisible = true + roomPreviewNoPreviewLabel.setText(R.string.room_preview_no_preview_join) + renderState(bestName, state.matrixItem().takeIf { state.roomAlias != null }, state.roomTopic) + } + else -> { + roomPreviewNoPreviewJoin.isVisible = false + roomPreviewNoPreviewLabel.isVisible = true + roomPreviewNoPreviewLabel.setText(R.string.room_preview_not_found) + renderState(bestName, null, state.roomTopic) + } + } + } + else -> { + // Render with initial state, no peeking + roomPreviewPeekingProgress.isVisible = false + roomPreviewNoPreviewJoin.isVisible = true + renderState(bestName, state.matrixItem(), state.roomTopic) + roomPreviewNoPreviewLabel.isVisible = false + } } } + + private fun renderState(roomName: String, matrixItem: MatrixItem?, topic: String?) { + // Toolbar + if (matrixItem != null) { + roomPreviewNoPreviewToolbarAvatar.isVisible = true + roomPreviewNoPreviewAvatar.isVisible = true + avatarRenderer.render(matrixItem, roomPreviewNoPreviewToolbarAvatar) + avatarRenderer.render(matrixItem, roomPreviewNoPreviewAvatar) + } else { + roomPreviewNoPreviewToolbarAvatar.isVisible = false + roomPreviewNoPreviewAvatar.isVisible = false + } + roomPreviewNoPreviewToolbarTitle.text = roomName + + // Screen + roomPreviewNoPreviewName.text = roomName + roomPreviewNoPreviewTopic.setTextOrHide(topic) + } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 900ba537b5..a18a41285b 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -16,8 +16,11 @@ package im.vector.app.features.roomdirectory.roompreview +import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject @@ -25,12 +28,17 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.roomdirectory.JoinState +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.internal.session.room.peeking.PeekResult +import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.android.sdk.rx.rx import timber.log.Timber @@ -56,6 +64,52 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini // Observe joined room (from the sync) observeRoomSummary() observeMembershipChanges() + + if (initialState.shouldPeekFromServer) { + setState { + copy(peekingState = Loading()) + } + viewModelScope.launch(Dispatchers.IO) { + val peekResult = tryOrNull { + awaitCallback { + session.peekRoom(initialState.roomAlias ?: initialState.roomId, it) + } + } + + when (peekResult) { + is PeekResult.Success -> { + setState { + copy( + roomId = peekResult.roomId, + avatarUrl = peekResult.avatarUrl, + roomAlias = peekResult.alias ?: initialState.roomAlias, + roomTopic = peekResult.topic, + homeServers = peekResult.viaServers, + peekingState = Success(PeekingState.FOUND) + ) + } + } + is PeekResult.PeekingNotAllowed -> { + setState { + copy( + roomId = peekResult.roomId, + roomAlias = peekResult.alias ?: initialState.roomAlias, + homeServers = peekResult.viaServers, + peekingState = Success(PeekingState.NO_ACCESS) + ) + } + } + PeekResult.UnknownAlias, + null -> { + setState { + copy( + peekingState = Success(PeekingState.NOT_FOUND) + ) + } + } + } + } + } } private fun observeRoomSummary() { @@ -82,7 +136,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini .subscribe { val changeMembership = it[initialState.roomId] ?: ChangeMembershipState.Unknown val joinState = when (changeMembership) { - is ChangeMembershipState.Joining -> JoinState.JOINING + is ChangeMembershipState.Joining -> JoinState.JOINING is ChangeMembershipState.FailedJoining -> JoinState.JOINING_ERROR // Other cases are handled by room summary else -> null diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt index 6816e54481..c0f7591f87 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt @@ -16,13 +16,31 @@ package im.vector.app.features.roomdirectory.roompreview +import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized import im.vector.app.features.roomdirectory.JoinState +import org.matrix.android.sdk.api.util.MatrixItem + +enum class PeekingState { + UNKNOWN, + FOUND, + NOT_FOUND, + NO_ACCESS +} data class RoomPreviewViewState( + + val peekingState: Async = Uninitialized, // The room id val roomId: String = "", val roomAlias: String? = null, + + val roomName: String? = null, + val roomTopic: String? = null, + val avatarUrl: String? = null, + + val shouldPeekFromServer: Boolean = false, /** * Can be empty when the server is the current user's home server. */ @@ -36,6 +54,14 @@ data class RoomPreviewViewState( constructor(args: RoomPreviewData) : this( roomId = args.roomId, roomAlias = args.roomAlias, - homeServers = args.homeServers + homeServers = args.homeServers, + roomName = args.roomName, + roomTopic = args.topic, + avatarUrl = args.avatarUrl, + shouldPeekFromServer = args.peekFromServer ) + + fun matrixItem() : MatrixItem { + return MatrixItem.RoomItem(roomId, roomName ?: roomAlias, avatarUrl) + } } diff --git a/vector/src/main/res/layout/fragment_room_preview_no_preview.xml b/vector/src/main/res/layout/fragment_room_preview_no_preview.xml index 2f4db6f116..906c7a21ab 100644 --- a/vector/src/main/res/layout/fragment_room_preview_no_preview.xml +++ b/vector/src/main/res/layout/fragment_room_preview_no_preview.xml @@ -54,6 +54,14 @@ + "This room can't be previewed" "The preview of world-readable room is not supported yet in Element" - + This room is not accessible at this time.\nTry again later, or ask a room admin to check if you have access. + "This room can't be previewed. Do you want to join it?" "Rooms" "Direct Messages" From 544345bbf34654f822a7f354bd49381817b7f368 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 11 Dec 2020 15:16:10 +0100 Subject: [PATCH 2/5] Update change log --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 1381a1e7ca..18ebc1dcbd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,11 +9,13 @@ Features ✨: Improvements 🙌: - Add Setting Item to Change PIN (#2462) - Improve room history visibility setting UX (#1579) + - Matrix.to deeplink custom scheme support Bugfix 🐛: - Fix cancellation of sending event (#2438) - Double bottomsheet effect after verify with passphrase - EditText cursor jumps to the start while typing fast (#2469) + - No known servers error is given when joining rooms on new Gitter bridge (#2516) Translations 🗣: - From 5461fd40609d504f4a330483cf4340b8484d56c2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 11 Dec 2020 16:35:04 +0100 Subject: [PATCH 3/5] Some cleanup up --- .../sdk/api/session/room/RoomService.kt | 5 +- .../api/session/room/peeking/PeekResult.kt | 37 +++++++++ .../session/room/DefaultRoomService.kt | 2 +- .../sdk/internal/session/room/RoomAPI.kt | 14 ++-- .../room/alias/GetRoomIdByAliasTask.kt | 4 +- .../session/room/peeking/PeekRoomTask.kt | 75 ++++++----------- .../room/peeking/ResolveRoomStateTask.kt | 2 +- vector/src/main/AndroidManifest.xml | 20 +++-- .../vector/app/features/home/HomeActivity.kt | 55 ++++++------- .../features/permalink/PermalinkHandler.kt | 6 +- .../roomdirectory/roompreview/PeekingState.kt | 23 ++++++ .../roompreview/RoomPreviewViewModel.kt | 80 ++++++++++--------- .../roompreview/RoomPreviewViewState.kt | 8 -- 13 files changed, 188 insertions(+), 143 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/PeekingState.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index 441a64e2c0..5f02b77a1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -23,10 +23,10 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams +import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription -import org.matrix.android.sdk.internal.session.room.peeking.PeekResult /** * This interface defines methods to get rooms. It's implemented at the session level. @@ -167,6 +167,9 @@ interface RoomService { */ fun getRoomMemberLive(userId: String, roomId: String): LiveData> + /** + * Get some state events about a room + */ fun getRoomState(roomId: String, callback: MatrixCallback>) /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt new file mode 100644 index 0000000000..db70dadef3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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.api.session.room.peeking + +sealed class PeekResult { + data class Success( + val roomId: String, + val alias: String?, + val name: String?, + val topic: String?, + val avatarUrl: String?, + val numJoinedMembers: Int?, + val viaServers: List + ) : PeekResult() + + data class PeekingNotAllowed( + val roomId: String, + val alias: String?, + val viaServers: List + ) : PeekResult() + + object UnknownAlias : PeekResult() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index e540105800..383dd876d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams +import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional @@ -41,7 +42,6 @@ import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomTask -import org.matrix.android.sdk.internal.session.room.peeking.PeekResult import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index f335987085..aa92c1cb3b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -183,7 +183,7 @@ internal interface RoomAPI { @Body body: ThreePidInviteBody): Call /** - * Send a generic state events + * Send a generic state event * * @param roomId the room id. * @param stateEventType the state event type @@ -195,7 +195,7 @@ internal interface RoomAPI { @Body params: JsonDict): Call /** - * Send a generic state events + * Send a generic state event * * @param roomId the room id. * @param stateEventType the state event type @@ -208,6 +208,13 @@ internal interface RoomAPI { @Path("state_key") stateKey: String, @Body params: JsonDict): Call + /** + * Get state events of a room + * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-state + */ + @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state") + fun getRoomState(@Path("roomId") roomId: String) : Call> + /** * Send a relation event to a room. * @@ -354,7 +361,4 @@ internal interface RoomAPI { fun deleteTag(@Path("userId") userId: String, @Path("roomId") roomId: String, @Path("tag") tag: String): Call - - @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state") - fun getRoomState(@Path("roomId") roomId: String) : Call> } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt index 2fe290ead2..543d605707 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt @@ -43,13 +43,13 @@ internal class DefaultGetRoomIdByAliasTask @Inject constructor( ) : GetRoomIdByAliasTask { override suspend fun execute(params: GetRoomIdByAliasTask.Params): Optional { - var roomId = Realm.getInstance(monarchy.realmConfiguration).use { + val roomId = Realm.getInstance(monarchy.realmConfiguration).use { RoomSummaryEntity.findByAlias(it, params.roomAlias)?.roomId } return if (roomId != null) { Optional.from(RoomAliasDescription(roomId)) } else if (!params.searchOnServer) { - Optional.from(null) + Optional.from(null) } else { val description = tryOrNull("## Failed to get roomId from alias") { executeRequest(eventBus) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt index ae557adb5f..9fba01efad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 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. @@ -26,32 +26,13 @@ import org.matrix.android.sdk.api.session.room.model.RoomNameContent import org.matrix.android.sdk.api.session.room.model.RoomTopicContent import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsFilter import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams +import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject -sealed class PeekResult { - data class Success( - val roomId: String, - val alias: String?, - val name: String?, - val topic: String?, - val avatarUrl: String?, - val numJoinedMembers: Int?, - val viaServers: List - ) : PeekResult() - - data class PeekingNotAllowed( - val roomId: String, - val alias: String?, - val viaServers: List - ) : PeekResult() - - object UnknownAlias : PeekResult() -} - internal interface PeekRoomTask : Task { data class Params( val roomIdOrAlias: String @@ -66,11 +47,10 @@ internal class DefaultPeekRoomTask @Inject constructor( ) : PeekRoomTask { override suspend fun execute(params: PeekRoomTask.Params): PeekResult { - val roomId: String? + val roomId: String val serverList: List - val isAlias: Boolean - if (MatrixPatterns.isRoomAlias(params.roomIdOrAlias)) { - isAlias = true + val isAlias = MatrixPatterns.isRoomAlias(params.roomIdOrAlias) + if (isAlias) { // get alias description val aliasDescription = getRoomIdByAliasTask .execute(GetRoomIdByAliasTask.Params(params.roomIdOrAlias, true)) @@ -80,7 +60,6 @@ internal class DefaultPeekRoomTask @Inject constructor( roomId = aliasDescription.roomId serverList = aliasDescription.servers } else { - isAlias = false roomId = params.roomIdOrAlias serverList = emptyList() } @@ -91,7 +70,7 @@ internal class DefaultPeekRoomTask @Inject constructor( // We cannot resolve this room :/ null } - RoomDirectoryVisibility.PUBLIC -> { + RoomDirectoryVisibility.PUBLIC -> { // Try to find it in directory val filter = if (isAlias) PublicRoomsFilter(searchTerm = params.roomIdOrAlias.substring(1)) else null @@ -121,34 +100,30 @@ internal class DefaultPeekRoomTask @Inject constructor( // mm... try to peek state ? maybe the room is not public but yet allow guest to get events? // this could be slow try { - val stateEvents = resolveRoomStateTask - .execute(ResolveRoomStateTask.Params(roomId)) - val name = stateEvents.lastOrNull { - it.type == EventType.STATE_ROOM_NAME - && it.stateKey == "" - }?.let { it.content?.toModel()?.name } + val stateEvents = resolveRoomStateTask.execute(ResolveRoomStateTask.Params(roomId)) + val name = stateEvents + .lastOrNull { it.type == EventType.STATE_ROOM_NAME && it.stateKey == "" } + ?.let { it.content?.toModel()?.name } - val topic = stateEvents.lastOrNull { - it.type == EventType.STATE_ROOM_TOPIC - && it.stateKey == "" - }?.let { it.content?.toModel()?.topic } + val topic = stateEvents + .lastOrNull { it.type == EventType.STATE_ROOM_TOPIC && it.stateKey == "" } + ?.let { it.content?.toModel()?.topic } - val avatarUrl = stateEvents.lastOrNull { - it.type == EventType.STATE_ROOM_AVATAR - }?.let { it.content?.toModel()?.avatarUrl } + val avatarUrl = stateEvents + .lastOrNull { it.type == EventType.STATE_ROOM_AVATAR } + ?.let { it.content?.toModel()?.avatarUrl } - val alias = stateEvents.lastOrNull { - it.type == EventType.STATE_ROOM_CANONICAL_ALIAS - }?.let { - it.content?.toModel()?.canonicalAlias - ?: it.content?.toModel()?.alternativeAliases?.firstOrNull() - } + val alias = stateEvents + .lastOrNull { it.type == EventType.STATE_ROOM_CANONICAL_ALIAS } + ?.let { + it.content?.toModel()?.canonicalAlias + ?: it.content?.toModel()?.alternativeAliases?.firstOrNull() + } // not sure if it's the right way to do that :/ - val memberCount = stateEvents.filter { - it.type == EventType.STATE_ROOM_MEMBER - && it.stateKey?.isNotEmpty() == true - }.distinctBy { it.stateKey } + val memberCount = stateEvents + .filter { it.type == EventType.STATE_ROOM_MEMBER && it.stateKey?.isNotEmpty() == true } + .distinctBy { it.stateKey } .count() return PeekResult.Success( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt index 289fdb498f..03ea2408f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/ResolveRoomStateTask.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 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. diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index fc3c7366ec..bf839b807c 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -81,8 +81,9 @@ android:resource="@xml/shortcuts" /> - + - + + - - + + diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 4ec786f841..e1837ccb1b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -126,9 +126,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet .observe() .subscribe { sharedAction -> when (sharedAction) { - is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) + is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START) - is HomeActivitySharedAction.OpenGroup -> { + is HomeActivitySharedAction.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) } @@ -145,9 +145,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet homeActivityViewModel.observeViewEvents { when (it) { is HomeActivityViewEvents.AskPasswordToInitCrossSigning -> handleAskPasswordToInitCrossSigning(it) - is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) - HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() - is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) + is HomeActivityViewEvents.OnNewSession -> handleOnNewSession(it) + HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush() + is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) }.exhaustive } homeActivityViewModel.subscribe(this) { renderState(it) } @@ -162,29 +162,27 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet private fun handleIntent(intent: Intent?) { intent?.dataString?.let { deepLink -> - val resolvedLink = if (deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { - deepLink - } else if (deepLink.startsWith(PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE)) { - // This is a bit hugly, but for now just convert to matrix.to link for compatibility - val service = activeSessionHolder.getSafeActiveSession()?.permalinkService() - val roomLinkPrefix = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" - val userPrefix = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" - when { - deepLink.startsWith(userPrefix) -> { - val userId = deepLink.substring(userPrefix.length) - service?.createPermalink(userId) + val resolvedLink = when { + deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink + deepLink.startsWith(PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { + // This is a bit ugly, but for now just convert to matrix.to link for compatibility + when { + deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) + deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length) + else -> null + }?.let { + activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) } - deepLink.startsWith(roomLinkPrefix) -> { - val param = deepLink.substring(roomLinkPrefix.length) - service?.createRoomPermalink(param) - } - else -> null } - } else null + else -> null + } - permalinkHandler.launch(this, resolvedLink, + permalinkHandler.launch( + context = this, + deepLink = resolvedLink, navigationInterceptor = this, - buildTask = true) + buildTask = true + ) // .delay(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe { isHandled -> @@ -198,7 +196,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet private fun renderState(state: HomeActivityViewState) { when (val status = state.initialSyncProgressServiceStatus) { - is InitialSyncProgressService.Status.Idle -> { + is InitialSyncProgressService.Status.Idle -> { waiting_view.isVisible = false } is InitialSyncProgressService.Status.Progressing -> { @@ -363,11 +361,11 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet bugReporter.openBugReportScreen(this, false) return true } - R.id.menu_home_filter -> { + R.id.menu_home_filter -> { navigator.openRoomsFiltering(this) return true } - R.id.menu_home_setting -> { + R.id.menu_home_setting -> { navigator.openSettings(this) return true } @@ -408,5 +406,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet putExtra(MvRx.KEY_ARG, args) } } + + private const val ROOM_LINK_PREFIX = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" + private const val USER_LINK_PREFIX = "${PermalinkService.MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" } } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 4e8b73cb2b..a7d69c783c 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -77,7 +77,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti buildTask: Boolean ): Single { return when (permalinkData) { - is PermalinkData.RoomLink -> { + is PermalinkData.RoomLink -> { permalinkData.getRoomId() .observeOn(AndroidSchedulers.mainThread()) .map { @@ -93,11 +93,11 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti true } } - is PermalinkData.GroupLink -> { + is PermalinkData.GroupLink -> { navigator.openGroupDetail(permalinkData.groupId, context, buildTask) Single.just(true) } - is PermalinkData.UserLink -> { + is PermalinkData.UserLink -> { if (navigationInterceptor?.navToMemberProfile(permalinkData.userId, rawLink) != true) { navigator.openRoomMemberProfile(userId = permalinkData.userId, roomId = null, context = context, buildTask = buildTask) } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/PeekingState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/PeekingState.kt new file mode 100644 index 0000000000..918264e594 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/PeekingState.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * 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 im.vector.app.features.roomdirectory.roompreview + +enum class PeekingState { + FOUND, + NOT_FOUND, + NO_ACCESS +} diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index a18a41285b..72c4c58a42 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -36,8 +36,8 @@ import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams -import org.matrix.android.sdk.internal.session.room.peeking.PeekResult import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.android.sdk.rx.rx import timber.log.Timber @@ -66,46 +66,50 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini observeMembershipChanges() if (initialState.shouldPeekFromServer) { - setState { - copy(peekingState = Loading()) + peekRoomFromServer() + } + } + + private fun peekRoomFromServer() { + setState { + copy(peekingState = Loading()) + } + viewModelScope.launch(Dispatchers.IO) { + val peekResult = tryOrNull { + awaitCallback { + session.peekRoom(initialState.roomAlias ?: initialState.roomId, it) + } } - viewModelScope.launch(Dispatchers.IO) { - val peekResult = tryOrNull { - awaitCallback { - session.peekRoom(initialState.roomAlias ?: initialState.roomId, it) + + when (peekResult) { + is PeekResult.Success -> { + setState { + copy( + roomId = peekResult.roomId, + avatarUrl = peekResult.avatarUrl, + roomAlias = peekResult.alias ?: initialState.roomAlias, + roomTopic = peekResult.topic, + homeServers = peekResult.viaServers, + peekingState = Success(PeekingState.FOUND) + ) } } - - when (peekResult) { - is PeekResult.Success -> { - setState { - copy( - roomId = peekResult.roomId, - avatarUrl = peekResult.avatarUrl, - roomAlias = peekResult.alias ?: initialState.roomAlias, - roomTopic = peekResult.topic, - homeServers = peekResult.viaServers, - peekingState = Success(PeekingState.FOUND) - ) - } + is PeekResult.PeekingNotAllowed -> { + setState { + copy( + roomId = peekResult.roomId, + roomAlias = peekResult.alias ?: initialState.roomAlias, + homeServers = peekResult.viaServers, + peekingState = Success(PeekingState.NO_ACCESS) + ) } - is PeekResult.PeekingNotAllowed -> { - setState { - copy( - roomId = peekResult.roomId, - roomAlias = peekResult.alias ?: initialState.roomAlias, - homeServers = peekResult.viaServers, - peekingState = Success(PeekingState.NO_ACCESS) - ) - } - } - PeekResult.UnknownAlias, - null -> { - setState { - copy( - peekingState = Success(PeekingState.NOT_FOUND) - ) - } + } + PeekResult.UnknownAlias, + null -> { + setState { + copy( + peekingState = Success(PeekingState.NOT_FOUND) + ) } } } @@ -136,7 +140,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini .subscribe { val changeMembership = it[initialState.roomId] ?: ChangeMembershipState.Unknown val joinState = when (changeMembership) { - is ChangeMembershipState.Joining -> JoinState.JOINING + is ChangeMembershipState.Joining -> JoinState.JOINING is ChangeMembershipState.FailedJoining -> JoinState.JOINING_ERROR // Other cases are handled by room summary else -> null diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt index c0f7591f87..5a73f29ca3 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt @@ -22,15 +22,7 @@ import com.airbnb.mvrx.Uninitialized import im.vector.app.features.roomdirectory.JoinState import org.matrix.android.sdk.api.util.MatrixItem -enum class PeekingState { - UNKNOWN, - FOUND, - NOT_FOUND, - NO_ACCESS -} - data class RoomPreviewViewState( - val peekingState: Async = Uninitialized, // The room id val roomId: String = "", From 071611b81c7088f142aec6502e7b1dad5c0fc1be Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 11 Dec 2020 16:38:22 +0100 Subject: [PATCH 4/5] We are not supposed to fallback on alternative alias --- .../sdk/internal/session/room/peeking/PeekRoomTask.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt index 9fba01efad..5a82d74537 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt @@ -115,10 +115,7 @@ internal class DefaultPeekRoomTask @Inject constructor( val alias = stateEvents .lastOrNull { it.type == EventType.STATE_ROOM_CANONICAL_ALIAS } - ?.let { - it.content?.toModel()?.canonicalAlias - ?: it.content?.toModel()?.alternativeAliases?.firstOrNull() - } + ?.let { it.content?.toModel()?.canonicalAlias } // not sure if it's the right way to do that :/ val memberCount = stateEvents From d8a1939c697098c5edd76f0de6599da97668f1fc Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 11 Dec 2020 17:50:59 +0100 Subject: [PATCH 5/5] Fix number of enum --- tools/check/forbidden_strings_in_code.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 63a3fad109..fc510e585c 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -164,7 +164,7 @@ Formatter\.formatShortFileSize===1 # android\.text\.TextUtils ### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt -enum class===83 +enum class===84 ### Do not import temporary legacy classes import org.matrix.android.sdk.internal.legacy.riot===3