diff --git a/changelog.d/5733.misc b/changelog.d/5733.misc new file mode 100644 index 0000000000..0dc1ef881c --- /dev/null +++ b/changelog.d/5733.misc @@ -0,0 +1 @@ +Communities/Groups are removed completely diff --git a/changelog.d/5733.sdk b/changelog.d/5733.sdk new file mode 100644 index 0000000000..0dc1ef881c --- /dev/null +++ b/changelog.d/5733.sdk @@ -0,0 +1 @@ +Communities/Groups are removed completely diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt index cc73e099b6..f22cfa369a 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt @@ -26,8 +26,6 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo -import org.matrix.android.sdk.api.session.group.GroupSummaryQueryParams -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.room.RoomSortOrder @@ -59,13 +57,6 @@ class FlowSession(private val session: Session) { } } - fun liveGroupSummaries(queryParams: GroupSummaryQueryParams): Flow> { - return session.groupService().getGroupSummariesLive(queryParams).asFlow() - .startWith(session.coroutineDispatchers.io) { - session.groupService().getGroupSummaries(queryParams) - } - } - fun liveSpaceSummaries(queryParams: SpaceSummaryQueryParams): Flow> { return session.spaceService().getSpaceSummariesLive(queryParams).asFlow() .startWith(session.coroutineDispatchers.io) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 1b01239de5..63c1c25130 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -33,7 +33,6 @@ import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.EventService import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker import org.matrix.android.sdk.api.session.file.FileService -import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.identity.IdentityService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService @@ -154,11 +153,6 @@ interface Session { */ fun roomDirectoryService(): RoomDirectoryService - /** - * Returns the GroupService associated with the session. - */ - fun groupService(): GroupService - /** * Returns the UserService associated with the session. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt deleted file mode 100644 index 25c69e5025..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.group - -/** - * This interface defines methods to interact within a group. - */ -interface Group { - val groupId: String - - /** - * This methods allows you to refresh data about this group. It will be reflected on the GroupSummary. - * The SDK also takes care of refreshing group data every hour. - * @return a Cancelable to be able to cancel requests. - */ - suspend fun fetchGroupData() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupService.kt deleted file mode 100644 index 1968af222a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupService.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.group - -import androidx.lifecycle.LiveData -import org.matrix.android.sdk.api.session.group.model.GroupSummary - -/** - * This interface defines methods to get groups. It's implemented at the session level. - */ -interface GroupService { - /** - * Get a group from a groupId. - * @param groupId the groupId to look for. - * @return the group with groupId or null - */ - fun getGroup(groupId: String): Group? - - /** - * Get a groupSummary from a groupId. - * @param groupId the groupId to look for. - * @return the groupSummary with groupId or null - */ - fun getGroupSummary(groupId: String): GroupSummary? - - /** - * Get a list of group summaries. This list is a snapshot of the data. - * @return the list of [GroupSummary] - */ - fun getGroupSummaries(groupSummaryQueryParams: GroupSummaryQueryParams): List - - /** - * Get a live list of group summaries. This list is refreshed as soon as the data changes. - * @return the [LiveData] of [GroupSummary] - */ - fun getGroupSummariesLive(groupSummaryQueryParams: GroupSummaryQueryParams): LiveData> -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupSummaryQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupSummaryQueryParams.kt deleted file mode 100644 index 5104b3ee53..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/GroupSummaryQueryParams.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.group - -import org.matrix.android.sdk.api.query.QueryStringValue -import org.matrix.android.sdk.api.session.room.model.Membership - -fun groupSummaryQueryParams(init: (GroupSummaryQueryParams.Builder.() -> Unit) = {}): GroupSummaryQueryParams { - return GroupSummaryQueryParams.Builder().apply(init).build() -} - -/** - * This class can be used to filter group summaries. - */ -data class GroupSummaryQueryParams( - val displayName: QueryStringValue, - val memberships: List -) { - - class Builder { - - var displayName: QueryStringValue = QueryStringValue.IsNotEmpty - var memberships: List = Membership.all() - - fun build() = GroupSummaryQueryParams( - displayName = displayName, - memberships = memberships - ) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/model/GroupSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/model/GroupSummary.kt deleted file mode 100644 index ef50fce82f..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/model/GroupSummary.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.group.model - -import org.matrix.android.sdk.api.session.room.model.Membership - -/** - * This class holds some data of a group. - * It can be retrieved through [org.matrix.android.sdk.api.session.group.GroupService] - */ -data class GroupSummary( - val groupId: String, - val membership: Membership, - val displayName: String = "", - val shortDescription: String = "", - val avatarUrl: String = "", - val roomIds: List = emptyList(), - val userIds: List = emptyList() -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt index e8d9c89b54..fc46c92117 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt @@ -54,7 +54,5 @@ sealed class PermalinkData { data class UserLink(val userId: String) : PermalinkData() - data class GroupLink(val groupId: String) : PermalinkData() - - data class FallbackLink(val uri: Uri) : PermalinkData() + data class FallbackLink(val uri: Uri, val isLegacyGroupLink: Boolean = false) : PermalinkData() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index 0168b7ac3a..3dccc3fbf2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -61,27 +61,29 @@ object PermalinkParser { val params = safeFragment .split(MatrixPatterns.SEP_REGEX) .filter { it.isNotEmpty() } - .map { URLDecoder.decode(it, "UTF-8") } .take(2) + val decodedParams = params + .map { URLDecoder.decode(it, "UTF-8") } + val identifier = params.getOrNull(0) - val extraParameter = params.getOrNull(1) + val decodedIdentifier = decodedParams.getOrNull(0) + val extraParameter = decodedParams.getOrNull(1) return when { - identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri) - MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier) - MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier) - MatrixPatterns.isRoomId(identifier) -> { - handleRoomIdCase(fragment, identifier, matrixToUri, extraParameter, viaQueryParameters) + identifier.isNullOrEmpty() || decodedIdentifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri) + MatrixPatterns.isUserId(decodedIdentifier) -> PermalinkData.UserLink(userId = decodedIdentifier) + MatrixPatterns.isRoomId(decodedIdentifier) -> { + handleRoomIdCase(fragment, decodedIdentifier, matrixToUri, extraParameter, viaQueryParameters) } - MatrixPatterns.isRoomAlias(identifier) -> { + MatrixPatterns.isRoomAlias(decodedIdentifier) -> { PermalinkData.RoomLink( - roomIdOrAlias = identifier, + roomIdOrAlias = decodedIdentifier, isRoomAlias = true, eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) }, viaParameters = viaQueryParameters ) } - else -> PermalinkData.FallbackLink(uri) + else -> PermalinkData.FallbackLink(uri, MatrixPatterns.isGroupId(identifier)) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt index 3d943473e4..00c6da00b7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt @@ -87,10 +87,6 @@ data class RoomSummaryQueryParams( * Used to filter room using the current space. */ val spaceFilter: SpaceFilter?, - /** - * Used to filter room using the current group. - */ - val activeGroupId: String? = null ) { /** @@ -106,7 +102,6 @@ data class RoomSummaryQueryParams( var excludeType: List? = listOf(RoomType.SPACE) var includeType: List? = null var spaceFilter: SpaceFilter? = null - var activeGroupId: String? = null fun build() = RoomSummaryQueryParams( displayName = displayName, @@ -117,7 +112,6 @@ data class RoomSummaryQueryParams( excludeType = excludeType, includeType = includeType, spaceFilter = spaceFilter, - activeGroupId = activeGroupId ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt index 407585b003..c4a3638ac4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStep.kt @@ -22,7 +22,6 @@ enum class InitialSyncStep { ImportingAccount, ImportingAccountCrypto, ImportingAccountRoom, - ImportingAccountGroups, ImportingAccountData, ImportingAccountJoinedRooms, ImportingAccountInvitedRooms, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt deleted file mode 100644 index 581e6824ee..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.sync.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class GroupSyncProfile( - /** - * The name of the group, if any. May be nil. - */ - @Json(name = "name") val name: String? = null, - - /** - * The URL for the group's avatar. May be nil. - */ - @Json(name = "avatar_url") val avatarUrl: String? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt deleted file mode 100644 index fd8710bbda..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.sync.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class GroupsSyncResponse( - /** - * Joined groups: An array of groups ids. - */ - @Json(name = "join") val join: Map = emptyMap(), - - /** - * Invitations. The groups that the user has been invited to: keys are groups ids. - */ - @Json(name = "invite") val invite: Map = emptyMap(), - - /** - * Left groups. An array of groups ids: the groups that the user has left or been banned from. - */ - @Json(name = "leave") val leave: Map = emptyMap() -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt deleted file mode 100644 index d41df9f0f6..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.sync.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class InvitedGroupSync( - /** - * The identifier of the inviter. - */ - @Json(name = "inviter") val inviter: String? = null, - - /** - * The group profile. - */ - @Json(name = "profile") val profile: GroupSyncProfile? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt index c70964a513..382d8a1740 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt @@ -65,10 +65,4 @@ data class SyncResponse( */ @Json(name = "org.matrix.msc2732.device_unused_fallback_key_types") val deviceUnusedFallbackKeyTypes: List? = null, - - /** - * List of groups. - */ - @Json(name = "groups") val groups: GroupsSyncResponse? = null - ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 26dd31dc2d..974f1cfcbe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.util import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.group.model.GroupSummary 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.RoomType @@ -113,19 +112,6 @@ sealed class MatrixItem( override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } - data class GroupItem( - override val id: String, - override val displayName: String? = null, - override val avatarUrl: String? = null - ) : - MatrixItem(id, displayName, avatarUrl) { - init { - if (BuildConfig.DEBUG) checkId() - } - - override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) - } - protected fun checkId() { if (!id.startsWith(getIdPrefix())) { error("Wrong usage of MatrixItem: check the id $id should start with ${getIdPrefix()}") @@ -144,7 +130,6 @@ sealed class MatrixItem( is RoomItem, is EveryoneInRoomItem -> '!' is RoomAliasItem -> '#' - is GroupItem -> '+' } fun firstLetterOfDisplayName(): String { @@ -196,8 +181,6 @@ sealed class MatrixItem( fun User.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl) -fun GroupSummary.toMatrixItem() = MatrixItem.GroupItem(groupId, displayName, avatarUrl) - fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) { MatrixItem.SpaceItem(roomId, displayName, avatarUrl) } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 665567bf2a..9be1717f32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -49,6 +49,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo028 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo029 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo030 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo031 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo032 import org.matrix.android.sdk.internal.util.Normalizer import timber.log.Timber import javax.inject.Inject @@ -63,7 +64,7 @@ internal class RealmSessionStoreMigration @Inject constructor( override fun equals(other: Any?) = other is RealmSessionStoreMigration override fun hashCode() = 1000 - val schemaVersion = 31L + val schemaVersion = 32L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Realm Session from $oldVersion to $newVersion") @@ -99,5 +100,6 @@ internal class RealmSessionStoreMigration @Inject constructor( if (oldVersion < 29) MigrateSessionTo029(realm).perform() if (oldVersion < 30) MigrateSessionTo030(realm).perform() if (oldVersion < 31) MigrateSessionTo031(realm).perform() + if (oldVersion < 32) MigrateSessionTo032(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/GroupSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/GroupSummaryMapper.kt deleted file mode 100644 index 13c3a796c4..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/GroupSummaryMapper.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.internal.database.mapper - -import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity - -internal object GroupSummaryMapper { - - fun map(groupSummaryEntity: GroupSummaryEntity): GroupSummary { - return GroupSummary( - groupSummaryEntity.groupId, - groupSummaryEntity.membership, - groupSummaryEntity.displayName, - groupSummaryEntity.shortDescription, - groupSummaryEntity.avatarUrl, - groupSummaryEntity.roomIds.toList(), - groupSummaryEntity.userIds.toList() - ) - } -} - -internal fun GroupSummaryEntity.asDomain(): GroupSummary { - return GroupSummaryMapper.map(this) -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt index aae80423ac..27423a9dca 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt @@ -49,7 +49,7 @@ internal class MigrateSessionTo010(realm: DynamicRealm) : RealmMigrator(realm, 1 realm.schema.get("RoomSummaryEntity") ?.addField(RoomSummaryEntityFields.ROOM_TYPE, String::class.java) ?.addField(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, String::class.java) - ?.addField(RoomSummaryEntityFields.GROUP_IDS, String::class.java) + ?.addField("groupIds", String::class.java) ?.transform { obj -> val creationEvent = realm.where("CurrentStateEventEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRooms.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo032.kt similarity index 51% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRooms.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo032.kt index 9e5d18225b..1506b8c8b3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRooms.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo032.kt @@ -1,11 +1,11 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 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 + * 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, @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.group.model +package org.matrix.android.sdk.internal.database.migration -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator -@JsonClass(generateAdapter = true) -internal data class GroupRooms( +internal class MigrateSessionTo032(realm: DynamicRealm) : RealmMigrator(realm, 32) { - @Json(name = "total_room_count_estimate") val totalRoomCountEstimate: Int? = null, - @Json(name = "chunk") val rooms: List = emptyList() - -) + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("RoomSummaryEntity") + ?.removeField("groupIds") + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt deleted file mode 100644 index 0120bb91d3..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.internal.database.model - -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.api.session.room.model.Membership - -/** - * This class is used to store group info (groupId and membership) from the sync response. - * Then GetGroupDataTask is called regularly to fetch group information from the homeserver. - */ -internal open class GroupEntity(@PrimaryKey var groupId: String = "") : - RealmObject() { - - private var membershipStr: String = Membership.NONE.name - var membership: Membership - get() { - return Membership.valueOf(membershipStr) - } - set(value) { - membershipStr = value.name - } - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt deleted file mode 100644 index d965148559..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.internal.database.model - -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.api.session.room.model.Membership - -internal open class GroupSummaryEntity( - @PrimaryKey var groupId: String = "", - var displayName: String = "", - var shortDescription: String = "", - var avatarUrl: String = "", - var roomIds: RealmList = RealmList(), - var userIds: RealmList = RealmList() -) : RealmObject() { - - private var membershipStr: String = Membership.NONE.name - var membership: Membership - get() { - return Membership.valueOf(membershipStr) - } - set(value) { - membershipStr = value.name - } - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt index cd755590be..5fb4c3f3d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt @@ -240,11 +240,6 @@ internal open class RoomSummaryEntity( if (value != field) field = value } - var groupIds: String? = null - set(value) { - if (value != field) field = value - } - @Index private var membershipStr: String = Membership.NONE.name diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt index 890c2300f8..d131589dd1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt @@ -32,8 +32,6 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit EventInsertEntity::class, TimelineEventEntity::class, FilterEntity::class, - GroupEntity::class, - GroupSummaryEntity::class, ReadReceiptEntity::class, RoomEntity::class, RoomSummaryEntity::class, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt deleted file mode 100644 index 020592d1dd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.internal.database.query - -import io.realm.Realm -import io.realm.RealmQuery -import io.realm.kotlin.where -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.internal.database.model.GroupEntity -import org.matrix.android.sdk.internal.database.model.GroupEntityFields -import org.matrix.android.sdk.internal.query.process - -internal fun GroupEntity.Companion.where(realm: Realm, groupId: String): RealmQuery { - return realm.where() - .equalTo(GroupEntityFields.GROUP_ID, groupId) -} - -internal fun GroupEntity.Companion.where(realm: Realm, memberships: List): RealmQuery { - return realm.where().process(GroupEntityFields.MEMBERSHIP_STR, memberships) -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt deleted file mode 100644 index 8131598d95..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.internal.database.query - -import io.realm.Realm -import io.realm.RealmQuery -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields - -internal fun GroupSummaryEntity.Companion.where(realm: Realm, groupId: String? = null): RealmQuery { - val query = realm.where() - if (groupId != null) { - query.equalTo(GroupSummaryEntityFields.GROUP_ID, groupId) - } - return query -} - -internal fun GroupSummaryEntity.Companion.where(realm: Realm, groupIds: List): RealmQuery { - return realm.where() - .`in`(GroupSummaryEntityFields.GROUP_ID, groupIds.toTypedArray()) -} - -internal fun GroupSummaryEntity.Companion.getOrCreate(realm: Realm, groupId: String): GroupSummaryEntity { - return where(realm, groupId).findFirst() ?: realm.createObject(groupId) -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index 7c50a0ff84..57db187bdc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -41,7 +41,6 @@ import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.EventService import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker import org.matrix.android.sdk.api.session.file.FileService -import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.identity.IdentityService import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService @@ -97,7 +96,6 @@ internal class DefaultSession @Inject constructor( private val sessionListeners: SessionListeners, private val roomService: Lazy, private val roomDirectoryService: Lazy, - private val groupService: Lazy, private val userService: Lazy, private val filterService: Lazy, private val federationService: Lazy, @@ -209,7 +207,6 @@ internal class DefaultSession @Inject constructor( override fun homeServerCapabilitiesService(): HomeServerCapabilitiesService = homeServerCapabilitiesService.get() override fun roomService(): RoomService = roomService.get() override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService.get() - override fun groupService(): GroupService = groupService.get() override fun userService(): UserService = userService.get() override fun signOutService(): SignOutService = signOutService.get() override fun filterService(): FilterService = filterService.get() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt index d3cae3ac2d..a79f35bcb6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt @@ -35,8 +35,6 @@ import org.matrix.android.sdk.internal.session.content.ContentModule import org.matrix.android.sdk.internal.session.content.UploadContentWorker import org.matrix.android.sdk.internal.session.contentscanner.ContentScannerModule import org.matrix.android.sdk.internal.session.filter.FilterModule -import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker -import org.matrix.android.sdk.internal.session.group.GroupModule import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesModule import org.matrix.android.sdk.internal.session.identity.IdentityModule import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManagerModule @@ -74,10 +72,8 @@ import org.matrix.android.sdk.internal.util.system.SystemModule SyncModule::class, HomeServerCapabilitiesModule::class, SignOutModule::class, - GroupModule::class, UserModule::class, FilterModule::class, - GroupModule::class, ContentModule::class, CacheModule::class, MediaModule::class, @@ -124,8 +120,6 @@ internal interface SessionComponent { fun inject(worker: RedactEventWorker) - fun inject(worker: GetGroupDataWorker) - fun inject(worker: UploadContentWorker) fun inject(worker: SyncWorker) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt index 76d956f9a5..3b0799438e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt @@ -25,7 +25,7 @@ internal class DisplayNameResolver @Inject constructor( private val matrixConfiguration: MatrixConfiguration ) { fun getBestName(matrixItem: MatrixItem): String { - return if (matrixItem is MatrixItem.GroupItem || matrixItem is MatrixItem.RoomAliasItem) { + return if (matrixItem is MatrixItem.RoomAliasItem) { // Best name is the id, and we keep the displayName of the room for the case we need the first letter matrixItem.id } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt deleted file mode 100644 index 9c37d4db6c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.internal.session.group - -import org.matrix.android.sdk.api.session.group.Group - -internal class DefaultGroup( - override val groupId: String, - private val getGroupDataTask: GetGroupDataTask -) : Group { - - override suspend fun fetchGroupData() { - val params = GetGroupDataTask.Params.FetchWithIds(listOf(groupId)) - getGroupDataTask.execute(params) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt deleted file mode 100644 index 9334d09377..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.internal.session.group - -import androidx.lifecycle.LiveData -import com.zhuinden.monarchy.Monarchy -import io.realm.Realm -import io.realm.RealmQuery -import org.matrix.android.sdk.api.session.group.Group -import org.matrix.android.sdk.api.session.group.GroupService -import org.matrix.android.sdk.api.session.group.GroupSummaryQueryParams -import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.internal.database.mapper.asDomain -import org.matrix.android.sdk.internal.database.model.GroupEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields -import org.matrix.android.sdk.internal.database.query.where -import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.internal.query.QueryStringValueProcessor -import org.matrix.android.sdk.internal.query.process -import org.matrix.android.sdk.internal.util.fetchCopyMap -import javax.inject.Inject - -internal class DefaultGroupService @Inject constructor( - @SessionDatabase private val monarchy: Monarchy, - private val groupFactory: GroupFactory, - private val queryStringValueProcessor: QueryStringValueProcessor, -) : GroupService { - - override fun getGroup(groupId: String): Group? { - return Realm.getInstance(monarchy.realmConfiguration).use { realm -> - GroupEntity.where(realm, groupId).findFirst()?.let { - groupFactory.create(groupId) - } - } - } - - override fun getGroupSummary(groupId: String): GroupSummary? { - return monarchy.fetchCopyMap( - { realm -> GroupSummaryEntity.where(realm, groupId).findFirst() }, - { it, _ -> it.asDomain() } - ) - } - - override fun getGroupSummaries(groupSummaryQueryParams: GroupSummaryQueryParams): List { - return monarchy.fetchAllMappedSync( - { groupSummariesQuery(it, groupSummaryQueryParams) }, - { it.asDomain() } - ) - } - - override fun getGroupSummariesLive(groupSummaryQueryParams: GroupSummaryQueryParams): LiveData> { - return monarchy.findAllMappedWithChanges( - { groupSummariesQuery(it, groupSummaryQueryParams) }, - { it.asDomain() } - ) - } - - private fun groupSummariesQuery(realm: Realm, queryParams: GroupSummaryQueryParams): RealmQuery { - return with(queryStringValueProcessor) { - GroupSummaryEntity.where(realm) - .process(GroupSummaryEntityFields.DISPLAY_NAME, queryParams.displayName) - .process(GroupSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt deleted file mode 100644 index 235291d061..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataTask.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.internal.session.group - -import com.zhuinden.monarchy.Monarchy -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.internal.database.model.GroupEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity -import org.matrix.android.sdk.internal.database.query.getOrCreate -import org.matrix.android.sdk.internal.database.query.where -import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver -import org.matrix.android.sdk.internal.network.executeRequest -import org.matrix.android.sdk.internal.session.group.model.GroupRooms -import org.matrix.android.sdk.internal.session.group.model.GroupSummaryResponse -import org.matrix.android.sdk.internal.session.group.model.GroupUsers -import org.matrix.android.sdk.internal.task.Task -import org.matrix.android.sdk.internal.util.awaitTransaction -import timber.log.Timber -import javax.inject.Inject - -internal interface GetGroupDataTask : Task { - sealed class Params { - object FetchAllActive : Params() - data class FetchWithIds(val groupIds: List) : Params() - } -} - -internal class DefaultGetGroupDataTask @Inject constructor( - private val groupAPI: GroupAPI, - @SessionDatabase private val monarchy: Monarchy, - private val globalErrorReceiver: GlobalErrorReceiver -) : GetGroupDataTask { - - private data class GroupData( - val groupId: String, - val groupSummary: GroupSummaryResponse, - val groupRooms: GroupRooms, - val groupUsers: GroupUsers - ) - - override suspend fun execute(params: GetGroupDataTask.Params) { - val groupIds = when (params) { - is GetGroupDataTask.Params.FetchAllActive -> { - getActiveGroupIds() - } - is GetGroupDataTask.Params.FetchWithIds -> { - params.groupIds - } - } - Timber.v("Fetch data for group with ids: ${groupIds.joinToString(";")}") - val data = groupIds.map { groupId -> - val groupSummary = executeRequest(globalErrorReceiver) { - groupAPI.getSummary(groupId) - } - val groupRooms = executeRequest(globalErrorReceiver) { - groupAPI.getRooms(groupId) - } - val groupUsers = executeRequest(globalErrorReceiver) { - groupAPI.getUsers(groupId) - } - GroupData(groupId, groupSummary, groupRooms, groupUsers) - } - insertInDb(data) - } - - private fun getActiveGroupIds(): List { - return monarchy.fetchAllMappedSync( - { realm -> - GroupEntity.where(realm, Membership.activeMemberships()) - }, - { it.groupId } - ) - } - - private suspend fun insertInDb(groupDataList: List) { - monarchy - .awaitTransaction { realm -> - groupDataList.forEach { groupData -> - - val groupSummaryEntity = GroupSummaryEntity.getOrCreate(realm, groupData.groupId) - - groupSummaryEntity.avatarUrl = groupData.groupSummary.profile?.avatarUrl ?: "" - val name = groupData.groupSummary.profile?.name - groupSummaryEntity.displayName = if (name.isNullOrEmpty()) groupData.groupId else name - groupSummaryEntity.shortDescription = groupData.groupSummary.profile?.shortDescription ?: "" - - groupSummaryEntity.roomIds.clear() - groupData.groupRooms.rooms.mapTo(groupSummaryEntity.roomIds) { it.roomId } - - groupSummaryEntity.userIds.clear() - groupData.groupUsers.users.mapTo(groupSummaryEntity.userIds) { it.userId } - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt deleted file mode 100644 index 21582cb4be..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.internal.session.group - -import android.content.Context -import androidx.work.WorkerParameters -import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.SessionManager -import org.matrix.android.sdk.internal.session.SessionComponent -import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -import org.matrix.android.sdk.internal.worker.SessionWorkerParams -import javax.inject.Inject - -/** - * Possible previous worker: None. - * Possible next worker : None. - */ -internal class GetGroupDataWorker(context: Context, params: WorkerParameters, sessionManager: SessionManager) : - SessionSafeCoroutineWorker(context, params, sessionManager, Params::class.java) { - - @JsonClass(generateAdapter = true) - internal data class Params( - override val sessionId: String, - override val lastFailureMessage: String? = null - ) : SessionWorkerParams - - @Inject lateinit var getGroupDataTask: GetGroupDataTask - - override fun injectWith(injector: SessionComponent) { - injector.inject(this) - } - - override suspend fun doSafeWork(params: Params): Result { - return runCatching { - getGroupDataTask.execute(GetGroupDataTask.Params.FetchAllActive) - }.fold( - { Result.success() }, - { Result.retry() } - ) - } - - override fun buildErrorParams(params: Params, message: String): Params { - return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupAPI.kt deleted file mode 100644 index c9d25b9104..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupAPI.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.internal.session.group - -import org.matrix.android.sdk.internal.network.NetworkConstants -import org.matrix.android.sdk.internal.session.group.model.GroupRooms -import org.matrix.android.sdk.internal.session.group.model.GroupSummaryResponse -import org.matrix.android.sdk.internal.session.group.model.GroupUsers -import retrofit2.http.GET -import retrofit2.http.Path - -internal interface GroupAPI { - - /** - * Request a group summary. - * - * @param groupId the group id - */ - @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "groups/{groupId}/summary") - suspend fun getSummary(@Path("groupId") groupId: String): GroupSummaryResponse - - /** - * Request the rooms list. - * - * @param groupId the group id - */ - @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "groups/{groupId}/rooms") - suspend fun getRooms(@Path("groupId") groupId: String): GroupRooms - - /** - * Request the users list. - * - * @param groupId the group id - */ - @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "groups/{groupId}/users") - suspend fun getUsers(@Path("groupId") groupId: String): GroupUsers -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt deleted file mode 100644 index 653d2a6933..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.internal.session.group - -import org.matrix.android.sdk.api.session.group.Group -import org.matrix.android.sdk.internal.session.SessionScope -import javax.inject.Inject - -internal interface GroupFactory { - fun create(groupId: String): Group -} - -@SessionScope -internal class DefaultGroupFactory @Inject constructor(private val getGroupDataTask: GetGroupDataTask) : - GroupFactory { - - override fun create(groupId: String): Group { - return DefaultGroup( - groupId = groupId, - getGroupDataTask = getGroupDataTask - ) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupModule.kt deleted file mode 100644 index 4dd61aa914..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupModule.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.internal.session.group - -import dagger.Binds -import dagger.Module -import dagger.Provides -import org.matrix.android.sdk.api.session.group.GroupService -import org.matrix.android.sdk.internal.session.SessionScope -import retrofit2.Retrofit - -@Module -internal abstract class GroupModule { - - @Module - companion object { - @Provides - @JvmStatic - @SessionScope - fun providesGroupAPI(retrofit: Retrofit): GroupAPI { - return retrofit.create(GroupAPI::class.java) - } - } - - @Binds - abstract fun bindGroupFactory(factory: DefaultGroupFactory): GroupFactory - - @Binds - abstract fun bindGetGroupDataTask(task: DefaultGetGroupDataTask): GetGroupDataTask - - @Binds - abstract fun bindGroupService(service: DefaultGroupService): GroupService -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupProfile.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupProfile.kt deleted file mode 100644 index 30eeb74b2e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupProfile.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * This class represents a community profile in the server responses. - */ -@JsonClass(generateAdapter = true) -internal data class GroupProfile( - - @Json(name = "short_description") val shortDescription: String? = null, - - /** - * Tell whether the group is public. - */ - @Json(name = "is_public") val isPublic: Boolean? = null, - - /** - * The URL for the group's avatar. May be nil. - */ - @Json(name = "avatar_url") val avatarUrl: String? = null, - - /** - * The group's name. - */ - @Json(name = "name") val name: String? = null, - - /** - * The optional HTML formatted string used to described the group. - */ - @Json(name = "long_description") val longDescription: String? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRoom.kt deleted file mode 100644 index 86e64f6797..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupRoom.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class GroupRoom( - - @Json(name = "aliases") val aliases: List = emptyList(), - @Json(name = "canonical_alias") val canonicalAlias: String? = null, - @Json(name = "name") val name: String? = null, - @Json(name = "num_joined_members") val numJoinedMembers: Int = 0, - @Json(name = "room_id") val roomId: String, - @Json(name = "topic") val topic: String? = null, - @Json(name = "world_readable") val worldReadable: Boolean = false, - @Json(name = "guest_can_join") val guestCanJoin: Boolean = false, - @Json(name = "avatar_url") val avatarUrl: String? = null - -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryResponse.kt deleted file mode 100644 index bf287e982c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryResponse.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * This class represents the summary of a community in the server response. - */ -@JsonClass(generateAdapter = true) -internal data class GroupSummaryResponse( - /** - * The group profile. - */ - @Json(name = "profile") val profile: GroupProfile? = null, - - /** - * The group users. - */ - @Json(name = "users_section") val usersSection: GroupSummaryUsersSection? = null, - - /** - * The current user status. - */ - @Json(name = "user") val user: GroupSummaryUser? = null, - - /** - * The rooms linked to the community. - */ - @Json(name = "rooms_section") val roomsSection: GroupSummaryRoomsSection? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryRoomsSection.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryRoomsSection.kt deleted file mode 100644 index 87d07167ce..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryRoomsSection.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * This class represents the community rooms in a group summary response. - */ -@JsonClass(generateAdapter = true) -internal data class GroupSummaryRoomsSection( - - @Json(name = "total_room_count_estimate") val totalRoomCountEstimate: Int? = null, - - @Json(name = "rooms") val rooms: List = emptyList() - - // TODO Check the meaning and the usage of these categories. This dictionary is empty FTM. - // public Map categories; -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUser.kt deleted file mode 100644 index 121ae6fd7d..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUser.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * This class represents the current user status in a group summary response. - */ -@JsonClass(generateAdapter = true) -internal data class GroupSummaryUser( - - /** - * The current user membership in this community. - */ - @Json(name = "membership") val membership: String? = null, - - /** - * Tell whether the user published this community on his profile. - */ - @Json(name = "is_publicised") val isPublicised: Boolean? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUsersSection.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUsersSection.kt deleted file mode 100644 index 63608c582a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupSummaryUsersSection.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * This class represents the community members in a group summary response. - */ - -@JsonClass(generateAdapter = true) -internal data class GroupSummaryUsersSection( - - @Json(name = "total_user_count_estimate") val totalUserCountEstimate: Int, - - @Json(name = "users") val users: List = emptyList() - - // TODO Check the meaning and the usage of these roles. This dictionary is empty FTM. - // public Map roles; -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUser.kt deleted file mode 100644 index a54c66535e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUser.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class GroupUser( - @Json(name = "display_name") val displayName: String = "", - @Json(name = "user_id") val userId: String, - @Json(name = "is_privileged") val isPrivileged: Boolean = false, - @Json(name = "avatar_url") val avatarUrl: String? = "", - @Json(name = "is_public") val isPublic: Boolean = false -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUsers.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUsers.kt deleted file mode 100644 index 9dd1339157..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/model/GroupUsers.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.internal.session.group.model - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class GroupUsers( - @Json(name = "total_user_count_estimate") val totalUserCountEstimate: Int, - @Json(name = "chunk") val users: List = emptyList() -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 8e20199135..3ecd47787f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -97,7 +97,6 @@ internal class PermalinkFactory @Inject constructor( url.startsWith(MATRIX_TO_URL_BASE) -> url.substring(MATRIX_TO_URL_BASE.length) clientBaseUrl != null && url.startsWith(clientBaseUrl) -> { when (PermalinkParser.parse(url)) { - is PermalinkData.GroupLink -> url.substring(clientBaseUrl.length + GROUP_PATH.length) is PermalinkData.RoomLink -> url.substring(clientBaseUrl.length + ROOM_PATH.length) is PermalinkData.UserLink -> url.substring(clientBaseUrl.length + USER_PATH.length) else -> null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index cb7dc270e8..80e27a1415 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -328,9 +328,6 @@ internal class RoomSummaryDataSource @Inject constructor( null -> Unit // nop } - queryParams.activeGroupId?.let { activeGroupId -> - query.contains(RoomSummaryEntityFields.GROUP_IDS, activeGroupId) - } return query } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index e4afe7aa49..a721aeb935 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -44,7 +44,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningSe import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields @@ -438,38 +437,6 @@ internal class RoomSummaryUpdater @Inject constructor( space.notificationCount = notificationCount } // xxx invites?? - - // LEGACY GROUPS - // lets mark rooms that belongs to groups - val existingGroups = GroupSummaryEntity.where(realm).findAll() - - // For rooms - realm.where(RoomSummaryEntity::class.java) - .process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships()) - .equalTo(RoomSummaryEntityFields.IS_DIRECT, false) - .findAll().forEach { room -> - val belongsTo = existingGroups.filter { it.roomIds.contains(room.roomId) } - room.groupIds = if (belongsTo.isEmpty()) { - null - } else { - "|${belongsTo.joinToString("|")}|" - } - } - - // For DMS - realm.where(RoomSummaryEntity::class.java) - .process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships()) - .equalTo(RoomSummaryEntityFields.IS_DIRECT, true) - .findAll().forEach { room -> - val belongsTo = existingGroups.filter { - it.userIds.intersect(room.otherMemberIds).isNotEmpty() - } - room.groupIds = if (belongsTo.isEmpty()) { - null - } else { - "|${belongsTo.joinToString("|")}|" - } - } }.also { Timber.v("## SPACES: Finish checking room hierarchy in $it ms") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 9e5302222a..392c73bd83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -16,47 +16,36 @@ package org.matrix.android.sdk.internal.session.sync -import androidx.work.ExistingPeriodicWorkPolicy import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.session.pushrules.PushRuleService import org.matrix.android.sdk.api.session.pushrules.RuleScope import org.matrix.android.sdk.api.session.sync.InitialSyncStep -import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId -import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.SessionListeners import org.matrix.android.sdk.internal.session.dispatchTo -import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.pushrules.ProcessEventForPushTask import org.matrix.android.sdk.internal.session.sync.handler.CryptoSyncHandler -import org.matrix.android.sdk.internal.session.sync.handler.GroupSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.PresenceSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.SyncResponsePostTreatmentAggregatorHandler import org.matrix.android.sdk.internal.session.sync.handler.UserAccountDataSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.room.RoomSyncHandler import org.matrix.android.sdk.internal.util.awaitTransaction -import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber -import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.system.measureTimeMillis -private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER" - internal class SyncResponseHandler @Inject constructor( @SessionDatabase private val monarchy: Monarchy, @SessionId private val sessionId: String, private val sessionManager: SessionManager, private val sessionListeners: SessionListeners, - private val workManagerProvider: WorkManagerProvider, private val roomSyncHandler: RoomSyncHandler, private val userAccountDataSyncHandler: UserAccountDataSyncHandler, - private val groupSyncHandler: GroupSyncHandler, private val cryptoSyncHandler: CryptoSyncHandler, private val aggregatorHandler: SyncResponsePostTreatmentAggregatorHandler, private val cryptoService: DefaultCryptoService, @@ -109,7 +98,7 @@ internal class SyncResponseHandler @Inject constructor( // IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local) measureTimeMillis { Timber.v("Handle rooms") - reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.7f) { + reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.8f) { if (syncResponse.rooms != null) { roomSyncHandler.handle(realm, syncResponse.rooms, isInitialSync, aggregator, reporter) } @@ -118,17 +107,6 @@ internal class SyncResponseHandler @Inject constructor( Timber.v("Finish handling rooms in $it ms") } - measureTimeMillis { - reportSubtask(reporter, InitialSyncStep.ImportingAccountGroups, 1, 0.1f) { - Timber.v("Handle groups") - if (syncResponse.groups != null) { - groupSyncHandler.handle(realm, syncResponse.groups, reporter) - } - } - }.also { - Timber.v("Finish handling groups in $it ms") - } - measureTimeMillis { reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) { Timber.v("Handle accountData") @@ -155,9 +133,6 @@ internal class SyncResponseHandler @Inject constructor( userAccountDataSyncHandler.synchronizeWithServerIfNeeded(it.invite) dispatchInvitedRoom(it) } - syncResponse.groups?.let { - scheduleGroupDataFetchingIfNeeded(it) - } Timber.v("On sync completed") cryptoSyncHandler.onSyncCompleted(syncResponse) @@ -177,31 +152,6 @@ internal class SyncResponseHandler @Inject constructor( } } - /** - * At the moment we don't get any group data through the sync, so we poll where every hour. - * You can also force to refetch group data using [Group] API. - */ - private fun scheduleGroupDataFetchingIfNeeded(groupsSyncResponse: GroupsSyncResponse) { - val groupIds = ArrayList() - groupIds.addAll(groupsSyncResponse.join.keys) - groupIds.addAll(groupsSyncResponse.invite.keys) - if (groupIds.isEmpty()) { - Timber.v("No new groups to fetch data for.") - return - } - Timber.v("There are ${groupIds.size} new groups to fetch data for.") - val getGroupDataWorkerParams = GetGroupDataWorker.Params(sessionId) - val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams) - - val getGroupWork = workManagerProvider.matrixPeriodicWorkRequestBuilder(1, TimeUnit.HOURS) - .setInputData(workData) - .setConstraints(WorkManagerProvider.workConstraints) - .build() - - workManagerProvider.workManager - .enqueueUniquePeriodicWork(GET_GROUP_DATA_WORKER, ExistingPeriodicWorkPolicy.REPLACE, getGroupWork) - } - private suspend fun checkPushRules(roomsSyncResponse: RoomsSyncResponse, isInitialSync: Boolean) { Timber.v("[PushRules] --> checkPushRules") if (isInitialSync) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt deleted file mode 100644 index 1983d9f433..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/GroupSyncHandler.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.internal.session.sync.handler - -import io.realm.Realm -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.sync.InitialSyncStep -import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse -import org.matrix.android.sdk.api.session.sync.model.InvitedGroupSync -import org.matrix.android.sdk.internal.database.model.GroupEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity -import org.matrix.android.sdk.internal.database.query.getOrCreate -import org.matrix.android.sdk.internal.database.query.where -import org.matrix.android.sdk.internal.session.sync.ProgressReporter -import org.matrix.android.sdk.internal.session.sync.mapWithProgress -import javax.inject.Inject - -internal class GroupSyncHandler @Inject constructor() { - - sealed class HandlingStrategy { - data class JOINED(val data: Map) : HandlingStrategy() - data class INVITED(val data: Map) : HandlingStrategy() - data class LEFT(val data: Map) : HandlingStrategy() - } - - fun handle( - realm: Realm, - roomsSyncResponse: GroupsSyncResponse, - reporter: ProgressReporter? = null - ) { - handleGroupSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), reporter) - handleGroupSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), reporter) - handleGroupSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), reporter) - } - - // PRIVATE METHODS ***************************************************************************** - - private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: ProgressReporter?) { - val groups = when (handlingStrategy) { - is HandlingStrategy.JOINED -> - handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.6f) { - handleJoinedGroup(realm, it.key) - } - - is HandlingStrategy.INVITED -> - handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.3f) { - handleInvitedGroup(realm, it.key) - } - - is HandlingStrategy.LEFT -> - handlingStrategy.data.mapWithProgress(reporter, InitialSyncStep.ImportingAccountGroups, 0.1f) { - handleLeftGroup(realm, it.key) - } - } - realm.insertOrUpdate(groups) - } - - private fun handleJoinedGroup( - realm: Realm, - groupId: String - ): GroupEntity { - val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId) - val groupSummaryEntity = GroupSummaryEntity.getOrCreate(realm, groupId) - groupEntity.membership = Membership.JOIN - groupSummaryEntity.membership = Membership.JOIN - return groupEntity - } - - private fun handleInvitedGroup( - realm: Realm, - groupId: String - ): GroupEntity { - val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId) - val groupSummaryEntity = GroupSummaryEntity.getOrCreate(realm, groupId) - groupEntity.membership = Membership.INVITE - groupSummaryEntity.membership = Membership.INVITE - return groupEntity - } - - private fun handleLeftGroup( - realm: Realm, - groupId: String - ): GroupEntity { - val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId) - val groupSummaryEntity = GroupSummaryEntity.getOrCreate(realm, groupId) - groupEntity.membership = Membership.LEAVE - groupSummaryEntity.membership = Membership.LEAVE - return groupEntity - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt index 52146ef484..83f9532870 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorker import org.matrix.android.sdk.internal.di.MatrixScope import org.matrix.android.sdk.internal.session.content.UploadContentWorker -import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.pushers.AddPusherWorker import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DeactivateLiveLocationShareWorker import org.matrix.android.sdk.internal.session.room.send.MultipleEventSendingDispatcherWorker @@ -53,8 +52,6 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage CheckFactoryWorker(appContext, workerParameters, true) AddPusherWorker::class.java.name -> AddPusherWorker(appContext, workerParameters, sessionManager) - GetGroupDataWorker::class.java.name -> - GetGroupDataWorker(appContext, workerParameters, sessionManager) MultipleEventSendingDispatcherWorker::class.java.name -> MultipleEventSendingDispatcherWorker(appContext, workerParameters, sessionManager) RedactEventWorker::class.java.name -> diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index d366927d6d..e1b8bfc474 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -40,20 +40,11 @@ import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoomSummary -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.sync.SyncRequestState import javax.inject.Inject import javax.inject.Singleton -sealed class RoomGroupingMethod { - data class ByLegacyGroup(val groupSummary: GroupSummary?) : RoomGroupingMethod() - data class BySpace(val spaceSummary: RoomSummary?) : RoomGroupingMethod() -} - -fun RoomGroupingMethod.space() = (this as? RoomGroupingMethod.BySpace)?.spaceSummary -fun RoomGroupingMethod.group() = (this as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary - /** * This class handles the global app state. * It requires to be added to ProcessLifecycleOwner.get().lifecycle @@ -68,29 +59,20 @@ class AppStateHandler @Inject constructor( ) : DefaultLifecycleObserver { private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) - private val selectedSpaceDataSource = BehaviorDataSource>(Option.empty()) + private val selectedSpaceDataSource = BehaviorDataSource>(Option.empty()) - val selectedRoomGroupingFlow = selectedSpaceDataSource.stream() + val selectedSpaceFlow = selectedSpaceDataSource.stream() private val spaceBackstack = ArrayDeque() - fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? { - // XXX we should somehow make it live :/ just a work around - // For example just after creating a space and switching to it the - // name in the app Bar could show Empty Room, and it will not update unless you - // switch space - return selectedSpaceDataSource.currentValue?.orNull()?.let { - if (it is RoomGroupingMethod.BySpace) { - // try to refresh sum? - it.spaceSummary?.roomId?.let { activeSessionHolder.getSafeActiveSession()?.roomService()?.getRoomSummary(it) }?.let { - RoomGroupingMethod.BySpace(it) - } ?: it - } else it + fun getCurrentSpace(): RoomSummary? { + return selectedSpaceDataSource.currentValue?.orNull()?.let { spaceSummary -> + activeSessionHolder.getSafeActiveSession()?.roomService()?.getRoomSummary(spaceSummary.roomId) } } fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false, isForwardNavigation: Boolean = true) { - val currentSpace = (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.space() + val currentSpace = selectedSpaceDataSource.currentValue?.orNull() val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return if (currentSpace != null && spaceId == currentSpace.roomId) return val spaceSum = spaceId?.let { uSession.getRoomSummary(spaceId) } @@ -100,11 +82,15 @@ class AppStateHandler @Inject constructor( } if (persistNow) { - uiStateRepository.storeGroupingMethod(true, uSession.sessionId) uiStateRepository.storeSelectedSpace(spaceSum?.roomId, uSession.sessionId) } - selectedSpaceDataSource.post(Option.just(RoomGroupingMethod.BySpace(spaceSum))) + if (spaceSum == null) { + selectedSpaceDataSource.post(Option.empty()) + } else { + selectedSpaceDataSource.post(Option.just(spaceSum)) + } + if (spaceId != null) { uSession.coroutineScope.launch(Dispatchers.IO) { tryOrNull { @@ -114,32 +100,13 @@ class AppStateHandler @Inject constructor( } } - fun setCurrentGroup(groupId: String?, session: Session? = null) { - val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return - if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.ByLegacyGroup && - groupId == selectedSpaceDataSource.currentValue?.orNull()?.group()?.groupId) return - val activeGroup = groupId?.let { uSession.groupService().getGroupSummary(groupId) } - selectedSpaceDataSource.post(Option.just(RoomGroupingMethod.ByLegacyGroup(activeGroup))) - if (groupId != null) { - uSession.coroutineScope.launch { - tryOrNull { - uSession.groupService().getGroup(groupId)?.fetchGroupData() - } - } - } - } - private fun observeActiveSession() { sessionDataSource.stream() .distinctUntilChanged() .onEach { // sessionDataSource could already return a session while activeSession holder still returns null it.orNull()?.let { session -> - if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) { - setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session) - } else { - setCurrentGroup(uiStateRepository.getSelectedGroup(session.sessionId), session) - } + setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session) observeSyncStatus(session) } } @@ -160,11 +127,7 @@ class AppStateHandler @Inject constructor( fun getSpaceBackstack() = spaceBackstack fun safeActiveSpaceId(): String? { - return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId - } - - fun safeActiveGroupId(): String? { - return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId + return selectedSpaceDataSource.currentValue?.orNull()?.roomId } override fun onResume(owner: LifecycleOwner) { @@ -174,15 +137,6 @@ class AppStateHandler @Inject constructor( override fun onPause(owner: LifecycleOwner) { coroutineScope.coroutineContext.cancelChildren() val session = activeSessionHolder.getSafeActiveSession() ?: return - when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) { - is RoomGroupingMethod.BySpace -> { - uiStateRepository.storeGroupingMethod(true, session.sessionId) - uiStateRepository.storeSelectedSpace(currentMethod.spaceSummary?.roomId, session.sessionId) - } - is RoomGroupingMethod.ByLegacyGroup -> { - uiStateRepository.storeGroupingMethod(false, session.sessionId) - uiStateRepository.storeSelectedGroup(currentMethod.groupSummary?.groupId, session.sessionId) - } - } + uiStateRepository.storeSelectedSpace(selectedSpaceDataSource.currentValue?.orNull()?.roomId, session.sessionId) } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt index b259477ebd..d8c3481eee 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt @@ -16,19 +16,13 @@ package im.vector.app.features.analytics.extensions -import im.vector.app.RoomGroupingMethod import im.vector.app.features.analytics.plan.ViewRoom import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomType -fun RoomSummary?.toAnalyticsViewRoom(trigger: ViewRoom.Trigger?, groupingMethod: RoomGroupingMethod? = null, viaKeyboard: Boolean? = null): ViewRoom { - val activeSpace = groupingMethod?.let { - when (it) { - is RoomGroupingMethod.BySpace -> it.spaceSummary?.toActiveSpace() ?: ViewRoom.ActiveSpace.Home - else -> null - } - } +fun RoomSummary?.toAnalyticsViewRoom(trigger: ViewRoom.Trigger?, selectedSpace: RoomSummary? = null, viaKeyboard: Boolean? = null): ViewRoom { + val activeSpace = selectedSpace?.toActiveSpace() ?: ViewRoom.ActiveSpace.Home return ViewRoom( isDM = this?.isDirect.orFalse(), diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt deleted file mode 100644 index 49987b69ea..0000000000 --- a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2019 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.autocomplete.group - -import com.airbnb.epoxy.TypedEpoxyController -import im.vector.app.features.autocomplete.AutocompleteClickListener -import im.vector.app.features.autocomplete.autocompleteMatrixItem -import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.api.util.toMatrixItem -import javax.inject.Inject - -class AutocompleteGroupController @Inject constructor() : TypedEpoxyController>() { - - var listener: AutocompleteClickListener? = null - - @Inject lateinit var avatarRenderer: AvatarRenderer - - override fun buildModels(data: List?) { - if (data.isNullOrEmpty()) { - return - } - val host = this - data.forEach { groupSummary -> - autocompleteMatrixItem { - id(groupSummary.groupId) - matrixItem(groupSummary.toMatrixItem()) - avatarRenderer(host.avatarRenderer) - clickListener { host.listener?.onItemClick(groupSummary) } - } - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupPresenter.kt deleted file mode 100644 index 32a1bed1c6..0000000000 --- a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupPresenter.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2019 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.autocomplete.group - -import android.content.Context -import androidx.recyclerview.widget.RecyclerView -import im.vector.app.features.autocomplete.AutocompleteClickListener -import im.vector.app.features.autocomplete.RecyclerViewPresenter -import org.matrix.android.sdk.api.query.QueryStringValue -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.group.groupSummaryQueryParams -import org.matrix.android.sdk.api.session.group.model.GroupSummary -import javax.inject.Inject - -class AutocompleteGroupPresenter @Inject constructor( - context: Context, - private val controller: AutocompleteGroupController, - private val session: Session -) : RecyclerViewPresenter(context), AutocompleteClickListener { - - init { - controller.listener = this - } - - fun clear() { - controller.listener = null - } - - override fun instantiateAdapter(): RecyclerView.Adapter<*> { - return controller.adapter - } - - override fun onItemClick(t: GroupSummary) { - dispatchClick(t) - } - - override fun onQuery(query: CharSequence?) { - val queryParams = groupSummaryQueryParams { - displayName = if (query.isNullOrBlank()) { - QueryStringValue.IsNotEmpty - } else { - QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE) - } - } - val groups = session.groupService().getGroupSummaries(queryParams) - .asSequence() - .sortedBy { it.displayName } - controller.setData(groups.toList()) - } -} diff --git a/vector/src/main/java/im/vector/app/features/displayname/Extension.kt b/vector/src/main/java/im/vector/app/features/displayname/Extension.kt index 6ca1d48464..71c1cbf27d 100644 --- a/vector/src/main/java/im/vector/app/features/displayname/Extension.kt +++ b/vector/src/main/java/im/vector/app/features/displayname/Extension.kt @@ -20,7 +20,7 @@ import org.matrix.android.sdk.api.util.MatrixItem fun MatrixItem.getBestName(): String { // Note: this code is copied from [DisplayNameResolver] in the SDK - return if (this is MatrixItem.GroupItem || this is MatrixItem.RoomAliasItem) { + return if (this is MatrixItem.RoomAliasItem) { // Best name is the id, and we keep the displayName of the room for the case we need the first letter id } else { diff --git a/vector/src/main/java/im/vector/app/features/grouplist/GroupSummaryItem.kt b/vector/src/main/java/im/vector/app/features/grouplist/GroupSummaryItem.kt deleted file mode 100644 index ce2b35b353..0000000000 --- a/vector/src/main/java/im/vector/app/features/grouplist/GroupSummaryItem.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2019 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.grouplist - -import android.widget.ImageView -import android.widget.TextView -import com.airbnb.epoxy.EpoxyAttribute -import com.airbnb.epoxy.EpoxyModelClass -import im.vector.app.R -import im.vector.app.core.epoxy.ClickListener -import im.vector.app.core.epoxy.VectorEpoxyHolder -import im.vector.app.core.epoxy.VectorEpoxyModel -import im.vector.app.core.epoxy.onClick -import im.vector.app.core.platform.CheckableConstraintLayout -import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.util.MatrixItem - -@EpoxyModelClass -abstract class GroupSummaryItem : VectorEpoxyModel(R.layout.item_group) { - - @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer - @EpoxyAttribute lateinit var matrixItem: MatrixItem - @EpoxyAttribute var selected: Boolean = false - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null - - override fun bind(holder: Holder) { - super.bind(holder) - holder.rootView.onClick(listener) - holder.groupNameView.text = matrixItem.displayName - holder.rootView.isChecked = selected - avatarRenderer.render(matrixItem, holder.avatarImageView) - } - - class Holder : VectorEpoxyHolder() { - val avatarImageView by bind(R.id.groupAvatarImageView) - val groupNameView by bind(R.id.groupNameView) - val rootView by bind(R.id.itemGroupLayout) - } -} 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 1c66cdda64..d82621977f 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 @@ -214,13 +214,12 @@ class HomeActivity : when (sharedAction) { is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) - is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment) is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId)) is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this)) is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId) is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId) HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) - HomeActivitySharedAction.CloseGroup -> closeGroup() + HomeActivitySharedAction.OnCloseSpace -> onCloseSpace() } } .launchIn(lifecycleScope) @@ -265,17 +264,6 @@ class HomeActivity : homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted) } - private fun openGroup(shouldClearFragment: Boolean) { - views.drawerLayout.closeDrawer(GravityCompat.START) - - // When switching from space to group or group to space, we need to reload the fragment - if (shouldClearFragment) { - replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) - } else { - // do nothing - } - } - private fun showSpaceSettings(spaceId: String) { // open bottom sheet SpaceSettingsMenuBottomSheet @@ -292,7 +280,7 @@ class HomeActivity : .show(supportFragmentManager, "SPACE_INVITE") } - private fun closeGroup() { + private fun onCloseSpace() { views.drawerLayout.openDrawer(GravityCompat.START) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt index a16d710f4e..d66bc94899 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt @@ -24,8 +24,7 @@ import im.vector.app.core.platform.VectorSharedAction sealed class HomeActivitySharedAction : VectorSharedAction { object OpenDrawer : HomeActivitySharedAction() object CloseDrawer : HomeActivitySharedAction() - data class OpenGroup(val shouldClearFragment: Boolean) : HomeActivitySharedAction() - object CloseGroup : HomeActivitySharedAction() + object OnCloseSpace : HomeActivitySharedAction() object AddSpace : HomeActivitySharedAction() data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction() data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index a3bc5144d1..828e4cc26c 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -30,7 +30,6 @@ import com.airbnb.mvrx.withState import com.google.android.material.badge.BadgeDrawable import im.vector.app.AppStateHandler import im.vector.app.R -import im.vector.app.RoomGroupingMethod import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.platform.OnBackPressed @@ -58,7 +57,6 @@ import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.workers.signout.BannerState import im.vector.app.features.workers.signout.ServerBackupStatusViewModel import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject @@ -130,11 +128,8 @@ class HomeDetailFragment @Inject constructor( views.bottomNavigationView.selectedItemId = it.currentTab.toMenuId() } - viewModel.onEach(HomeDetailViewState::roomGroupingMethod) { roomGroupingMethod -> - when (roomGroupingMethod) { - is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary) - is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary) - } + viewModel.onEach(HomeDetailViewState::selectedSpace) { selectedSpace -> + onSpaceChange(selectedSpace) } viewModel.onEach(HomeDetailViewState::currentTab) { currentTab -> @@ -188,26 +183,16 @@ class HomeDetailFragment @Inject constructor( } private fun navigateBack() { - try { - val lastSpace = appStateHandler.getSpaceBackstack().removeLast() - setCurrentSpace(lastSpace) - } catch (e: NoSuchElementException) { - navigateUpOneSpace() - } + val previousSpaceId = appStateHandler.getSpaceBackstack().removeLastOrNull() + val parentSpaceId = appStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull() + setCurrentSpace(previousSpaceId ?: parentSpaceId) } private fun setCurrentSpace(spaceId: String?) { appStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false) - sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup) + sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace) } - private fun navigateUpOneSpace() { - val parentId = getCurrentSpace()?.flattenParentIds?.lastOrNull() - setCurrentSpace(parentId) - } - - private fun getCurrentSpace() = (appStateHandler.getCurrentRoomGroupingMethod() as? RoomGroupingMethod.BySpace)?.spaceSummary - private fun handleCallStarted() { dismissLoadingDialog() val fragmentTag = HomeTab.DialPad.toFragmentTag() @@ -227,10 +212,8 @@ class HomeDetailFragment @Inject constructor( } private fun refreshSpaceState() { - when (val roomGroupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary) - is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary) - else -> Unit + appStateHandler.getCurrentSpace()?.let { + onSpaceChange(it) } } @@ -291,15 +274,6 @@ class HomeDetailFragment @Inject constructor( ) } - private fun onGroupChange(groupSummary: GroupSummary?) { - if (groupSummary == null) { - views.groupToolbarSpaceTitleView.isVisible = false - } else { - views.groupToolbarSpaceTitleView.isVisible = true - views.groupToolbarSpaceTitleView.text = groupSummary.displayName - } - } - private fun onSpaceChange(spaceSummary: RoomSummary?) { if (spaceSummary == null) { views.groupToolbarSpaceTitleView.isVisible = false @@ -335,16 +309,9 @@ class HomeDetailFragment @Inject constructor( } views.homeToolbarContent.debouncedClicks { - withState(viewModel) { - when (it.roomGroupingMethod) { - is RoomGroupingMethod.ByLegacyGroup -> { - // do nothing - } - is RoomGroupingMethod.BySpace -> { - it.roomGroupingMethod.spaceSummary?.let { spaceSummary -> - sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(spaceSummary.roomId)) - } - } + withState(viewModel) { viewState -> + viewState.selectedSpace?.let { + sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(it.roomId)) } } } @@ -499,7 +466,7 @@ class HomeDetailFragment @Inject constructor( return this } - override fun onBackPressed(toolbarButton: Boolean) = if (getCurrentSpace() != null) { + override fun onBackPressed(toolbarButton: Boolean) = if (appStateHandler.getCurrentSpace() != null) { navigateBack() true } else { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 485d1e33ec..357d2b7c69 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -23,7 +23,6 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.singletonEntryPoint @@ -208,16 +207,16 @@ class HomeDetailViewModel @AssistedInject constructor( } private fun observeRoomGroupingMethod() { - appStateHandler.selectedRoomGroupingFlow + appStateHandler.selectedSpaceFlow .setOnEach { copy( - roomGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) + selectedSpace = it.orNull() ) } } private fun observeRoomSummaries() { - appStateHandler.selectedRoomGroupingFlow.distinctUntilChanged().flatMapLatest { + appStateHandler.selectedSpaceFlow.distinctUntilChanged().flatMapLatest { // we use it as a trigger to all changes in room, but do not really load // the actual models session.roomService().getPagedRoomSummariesLive( @@ -229,67 +228,55 @@ class HomeDetailViewModel @AssistedInject constructor( } .throttleFirst(300) .onEach { - when (val groupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.ByLegacyGroup -> { - // TODO!! - } - is RoomGroupingMethod.BySpace -> { - val activeSpaceRoomId = groupingMethod.spaceSummary?.roomId - var dmInvites = 0 - var roomsInvite = 0 - if (autoAcceptInvites.showInvites()) { - dmInvites = session.roomService().getRoomSummaries( - roomSummaryQueryParams { - memberships = listOf(Membership.INVITE) - roomCategoryFilter = RoomCategoryFilter.ONLY_DM - spaceFilter = activeSpaceRoomId?.let { SpaceFilter.ActiveSpace(it) } - } - ).size + val activeSpaceRoomId = appStateHandler.getCurrentSpace()?.roomId + var dmInvites = 0 + var roomsInvite = 0 + if (autoAcceptInvites.showInvites()) { + dmInvites = session.roomService().getRoomSummaries( + roomSummaryQueryParams { + memberships = listOf(Membership.INVITE) + roomCategoryFilter = RoomCategoryFilter.ONLY_DM + spaceFilter = activeSpaceRoomId?.let { SpaceFilter.ActiveSpace(it) } + } + ).size - roomsInvite = session.roomService().getRoomSummaries( - roomSummaryQueryParams { - memberships = listOf(Membership.INVITE) - roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - spaceFilter = groupingMethod.toActiveSpaceOrOrphanRooms() - } - ).size + roomsInvite = session.roomService().getRoomSummaries( + roomSummaryQueryParams { + memberships = listOf(Membership.INVITE) + roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + spaceFilter = activeSpaceRoomId.toActiveSpaceOrOrphanRooms() + } + ).size + } + + val dmRooms = session.roomService().getNotificationCountForRooms( + roomSummaryQueryParams { + memberships = listOf(Membership.JOIN) + roomCategoryFilter = RoomCategoryFilter.ONLY_DM + spaceFilter = activeSpaceRoomId?.let { SpaceFilter.ActiveSpace(it) } } + ) - val dmRooms = session.roomService().getNotificationCountForRooms( - roomSummaryQueryParams { - memberships = listOf(Membership.JOIN) - roomCategoryFilter = RoomCategoryFilter.ONLY_DM - spaceFilter = activeSpaceRoomId?.let { SpaceFilter.ActiveSpace(it) } - } - ) - - val otherRooms = session.roomService().getNotificationCountForRooms( - roomSummaryQueryParams { - memberships = listOf(Membership.JOIN) - roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - spaceFilter = groupingMethod.toActiveSpaceOrOrphanRooms() - } - ) - - setState { - copy( - notificationCountCatchup = dmRooms.totalCount + otherRooms.totalCount + roomsInvite + dmInvites, - notificationHighlightCatchup = dmRooms.isHighlight || otherRooms.isHighlight || (dmInvites + roomsInvite) > 0, - notificationCountPeople = dmRooms.totalCount + dmInvites, - notificationHighlightPeople = dmRooms.isHighlight || dmInvites > 0, - notificationCountRooms = otherRooms.totalCount + roomsInvite, - notificationHighlightRooms = otherRooms.isHighlight || roomsInvite > 0, - hasUnreadMessages = dmRooms.totalCount + otherRooms.totalCount > 0 - ) + val otherRooms = session.roomService().getNotificationCountForRooms( + roomSummaryQueryParams { + memberships = listOf(Membership.JOIN) + roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + spaceFilter = activeSpaceRoomId.toActiveSpaceOrOrphanRooms() } - } - null -> Unit + ) + + setState { + copy( + notificationCountCatchup = dmRooms.totalCount + otherRooms.totalCount + roomsInvite + dmInvites, + notificationHighlightCatchup = dmRooms.isHighlight || otherRooms.isHighlight || (dmInvites + roomsInvite) > 0, + notificationCountPeople = dmRooms.totalCount + dmInvites, + notificationHighlightPeople = dmRooms.isHighlight || dmInvites > 0, + notificationCountRooms = otherRooms.totalCount + roomsInvite, + notificationHighlightRooms = otherRooms.isHighlight || roomsInvite > 0, + hasUnreadMessages = dmRooms.totalCount + otherRooms.totalCount > 0 + ) } } .launchIn(viewModelScope) } - - private fun RoomGroupingMethod.BySpace.toActiveSpaceOrOrphanRooms(): SpaceFilter { - return spaceSummary?.roomId.toActiveSpaceOrOrphanRooms() - } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt index 7b8319d8d1..7fbd5b2bf6 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt @@ -21,14 +21,13 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized import im.vector.app.R -import im.vector.app.RoomGroupingMethod import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.util.MatrixItem data class HomeDetailViewState( - val roomGroupingMethod: RoomGroupingMethod = RoomGroupingMethod.BySpace(null), + val selectedSpace: RoomSummary? = null, val myMatrixItem: MatrixItem? = null, val asyncRooms: Async> = Uninitialized, val currentTab: HomeTab = HomeTab.RoomList(RoomListDisplayMode.PEOPLE), diff --git a/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt b/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt index 884b4266cd..f4626477c7 100644 --- a/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/InitSyncStepFormatter.kt @@ -32,7 +32,6 @@ class InitSyncStepFormatter @Inject constructor( InitialSyncStep.ImportingAccount -> R.string.initial_sync_start_importing_account InitialSyncStep.ImportingAccountCrypto -> R.string.initial_sync_start_importing_account_crypto InitialSyncStep.ImportingAccountRoom -> R.string.initial_sync_start_importing_account_rooms - InitialSyncStep.ImportingAccountGroups -> R.string.initial_sync_start_importing_account_groups InitialSyncStep.ImportingAccountData -> R.string.initial_sync_start_importing_account_data InitialSyncStep.ImportingAccountJoinedRooms -> R.string.initial_sync_start_importing_account_joined_rooms InitialSyncStep.ImportingAccountInvitedRooms -> R.string.initial_sync_start_importing_account_invited_rooms diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index 723ca7caae..f2e6b7e064 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -23,7 +23,6 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyAction @@ -110,8 +109,8 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor( } combine( - appStateHandler.selectedRoomGroupingFlow.distinctUntilChanged(), - appStateHandler.selectedRoomGroupingFlow.flatMapLatest { + appStateHandler.selectedSpaceFlow.distinctUntilChanged(), + appStateHandler.selectedSpaceFlow.flatMapLatest { roomService.getPagedRoomSummariesLive( roomSummaryQueryParams { this.memberships = Membership.activeMemberships() @@ -119,74 +118,57 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor( ).asFlow() .throttleFirst(300) } - ) { groupingMethod, _ -> - when (groupingMethod.orNull()) { - is RoomGroupingMethod.ByLegacyGroup -> { - // currently not supported - CountInfo( - RoomAggregateNotificationCount(0, 0), - RoomAggregateNotificationCount(0, 0) - ) - } - is RoomGroupingMethod.BySpace -> { - val selectedSpace = appStateHandler.safeActiveSpaceId() + ) { selectedSpaceOption, _ -> + val selectedSpace = selectedSpaceOption.orNull()?.roomId - val inviteCount = if (autoAcceptInvites.hideInvites) { - 0 - } else { - roomService.getRoomSummaries( - roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } - ).size - } - - val spaceInviteCount = if (autoAcceptInvites.hideInvites) { - 0 - } else { - roomService.getRoomSummaries( - spaceSummaryQueryParams { - this.memberships = listOf(Membership.INVITE) - } - ).size - } - - val totalCount = roomService.getNotificationCountForRooms( - roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.spaceFilter = SpaceFilter.OrphanRooms.takeIf { - !vectorPreferences.prefSpacesShowAllRoomInHome() - } - } - ) - - val counts = RoomAggregateNotificationCount( - totalCount.notificationCount + inviteCount, - totalCount.highlightCount + inviteCount - ) - val rootCounts = session.spaceService().getRootSpaceSummaries() - .filter { - // filter out current selection - it.roomId != selectedSpace - } - - CountInfo( - homeCount = counts, - otherCount = RoomAggregateNotificationCount( - notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) + - (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) + - spaceInviteCount, - highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) + - (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) + - spaceInviteCount - ) - ) - } - null -> { - CountInfo( - RoomAggregateNotificationCount(0, 0), - RoomAggregateNotificationCount(0, 0) - ) - } + val inviteCount = if (autoAcceptInvites.hideInvites) { + 0 + } else { + roomService.getRoomSummaries( + roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } + ).size } + + val spaceInviteCount = if (autoAcceptInvites.hideInvites) { + 0 + } else { + roomService.getRoomSummaries( + spaceSummaryQueryParams { + this.memberships = listOf(Membership.INVITE) + } + ).size + } + + val totalCount = roomService.getNotificationCountForRooms( + roomSummaryQueryParams { + this.memberships = listOf(Membership.JOIN) + this.spaceFilter = SpaceFilter.OrphanRooms.takeIf { + !vectorPreferences.prefSpacesShowAllRoomInHome() + } + } + ) + + val counts = RoomAggregateNotificationCount( + totalCount.notificationCount + inviteCount, + totalCount.highlightCount + inviteCount + ) + val rootCounts = session.spaceService().getRootSpaceSummaries() + .filter { + // filter out current selection + it.roomId != selectedSpace + } + + CountInfo( + homeCount = counts, + otherCount = RoomAggregateNotificationCount( + notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) + + (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount, + highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) + + (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount + ) + ) } .flowOn(Dispatchers.Default) .execute { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 68053ed890..51e1fb06f2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -32,7 +32,6 @@ import im.vector.app.core.glide.GlideRequests import im.vector.app.features.autocomplete.command.AutocompleteCommandPresenter import im.vector.app.features.autocomplete.command.CommandAutocompletePolicy import im.vector.app.features.autocomplete.emoji.AutocompleteEmojiPresenter -import im.vector.app.features.autocomplete.group.AutocompleteGroupPresenter import im.vector.app.features.autocomplete.member.AutocompleteMemberItem import im.vector.app.features.autocomplete.member.AutocompleteMemberPresenter import im.vector.app.features.autocomplete.room.AutocompleteRoomPresenter @@ -41,7 +40,6 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan import im.vector.app.features.themes.ThemeUtils -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toEveryoneInRoomMatrixItem @@ -56,7 +54,6 @@ class AutoCompleter @AssistedInject constructor( autocompleteCommandPresenterFactory: AutocompleteCommandPresenter.Factory, private val autocompleteMemberPresenterFactory: AutocompleteMemberPresenter.Factory, private val autocompleteRoomPresenter: AutocompleteRoomPresenter, - private val autocompleteGroupPresenter: AutocompleteGroupPresenter, private val autocompleteEmojiPresenter: AutocompleteEmojiPresenter ) { @@ -89,7 +86,6 @@ class AutoCompleter @AssistedInject constructor( val backgroundDrawable = ColorDrawable(ThemeUtils.getColor(editText.context, android.R.attr.colorBackground)) setupCommands(backgroundDrawable, editText) setupMembers(backgroundDrawable, editText) - setupGroups(backgroundDrawable, editText) setupEmojis(backgroundDrawable, editText) setupRooms(backgroundDrawable, editText) } @@ -97,7 +93,6 @@ class AutoCompleter @AssistedInject constructor( fun clear() { this.editText = null autocompleteEmojiPresenter.clear() - autocompleteGroupPresenter.clear() autocompleteRoomPresenter.clear() autocompleteCommandPresenter.clear() autocompleteMemberPresenter.clear() @@ -170,24 +165,6 @@ class AutoCompleter @AssistedInject constructor( .build() } - private fun setupGroups(backgroundDrawable: ColorDrawable, editText: EditText) { - Autocomplete.on(editText) - .with(CharPolicy(TRIGGER_AUTO_COMPLETE_GROUPS, true)) - .with(autocompleteGroupPresenter) - .with(ELEVATION_DP) - .with(backgroundDrawable) - .with(object : AutocompleteCallback { - override fun onPopupItemClicked(editable: Editable, item: GroupSummary): Boolean { - insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_GROUPS, item.toMatrixItem()) - return true - } - - override fun onPopupVisibilityChanged(shown: Boolean) { - } - }) - .build() - } - private fun setupEmojis(backgroundDrawable: Drawable, editText: EditText) { Autocomplete.on(editText) .with(CharPolicy(TRIGGER_AUTO_COMPLETE_EMOJIS, false)) @@ -262,7 +239,6 @@ class AutoCompleter @AssistedInject constructor( private const val ELEVATION_DP = 6f private const val TRIGGER_AUTO_COMPLETE_MEMBERS = '@' private const val TRIGGER_AUTO_COMPLETE_ROOMS = '#' - private const val TRIGGER_AUTO_COMPLETE_GROUPS = '+' private const val TRIGGER_AUTO_COMPLETE_EMOJIS = ':' } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 194db8bce7..e305ccbec1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -61,7 +61,6 @@ import im.vector.app.features.raw.wellknown.withElementWellKnown import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorPreferences -import im.vector.app.space import im.vector.lib.core.utils.flow.chunk import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow @@ -219,7 +218,7 @@ class TimelineViewModel @AssistedInject constructor( if (initialState.switchToParentSpace) { // We are coming from a notification, try to switch to the most relevant space // so that when hitting back the room will appear in the list - appStateHandler.getCurrentRoomGroupingMethod()?.space().let { currentSpace -> + appStateHandler.getCurrentSpace().let { currentSpace -> val currentRoomSummary = room.roomSummary() ?: return@let // nothing we are good if ((currentSpace == null && !vectorPreferences.prefSpacesShowAllRoomInHome()) || diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt index df009e8d6b..269af4afa0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt @@ -24,7 +24,6 @@ import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem import im.vector.app.features.home.room.filtered.filteredRoomFooterItem -import im.vector.app.space import javax.inject.Inject class RoomListFooterController @Inject constructor( @@ -42,7 +41,7 @@ class RoomListFooterController @Inject constructor( id("filter_footer") listener(host.listener) currentFilter(data.roomFilter) - inSpace(data.currentRoomGrouping.invoke()?.space() != null) + inSpace(data.asyncSelectedSpace.invoke() != null) } } else -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt index c98f613c40..42634c237a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt @@ -16,8 +16,443 @@ package im.vector.app.features.home.room.list +import androidx.annotation.StringRes +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.asFlow +import androidx.lifecycle.liveData +import androidx.paging.PagedList +import com.airbnb.mvrx.Async +import im.vector.app.AppStateHandler +import im.vector.app.R +import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.RoomListDisplayMode +import im.vector.app.features.invite.AutoAcceptInvites +import im.vector.app.features.invite.showInvites +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.update +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.query.RoomCategoryFilter +import org.matrix.android.sdk.api.query.RoomTagQueryFilter +import org.matrix.android.sdk.api.query.SpaceFilter +import org.matrix.android.sdk.api.query.toActiveSpaceOrOrphanRooms +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.getRoomSummary +import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams +import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount +import timber.log.Timber -interface RoomListSectionBuilder { - fun buildSections(mode: RoomListDisplayMode): List +class RoomListSectionBuilder( + private val session: Session, + private val stringProvider: StringProvider, + private val appStateHandler: AppStateHandler, + private val viewModelScope: CoroutineScope, + private val autoAcceptInvites: AutoAcceptInvites, + private val onUpdatable: (UpdatableLivePageResult) -> Unit, + private val suggestedRoomJoiningState: LiveData>>, + private val onlyOrphansInHome: Boolean = false +) { + + private val pagedListConfig = PagedList.Config.Builder() + .setPageSize(10) + .setInitialLoadSizeHint(20) + .setEnablePlaceholders(true) + .setPrefetchDistance(10) + .build() + + fun buildSections(mode: RoomListDisplayMode): List { + val sections = mutableListOf() + val activeSpaceAwareQueries = mutableListOf() + when (mode) { + RoomListDisplayMode.PEOPLE -> { + // 4 sections Invites / Fav / Dms / Low Priority + buildDmSections(sections, activeSpaceAwareQueries) + } + RoomListDisplayMode.ROOMS -> { + // 6 sections invites / Fav / Rooms / Low Priority / Server notice / Suggested rooms + buildRoomsSections(sections, activeSpaceAwareQueries) + } + RoomListDisplayMode.FILTERED -> { + // Used when searching for rooms + buildFilteredSection(sections) + } + RoomListDisplayMode.NOTIFICATIONS -> { + buildNotificationsSection(sections, activeSpaceAwareQueries) + } + } + + appStateHandler.selectedSpaceFlow + .distinctUntilChanged() + .onEach { selectedSpaceOption -> + val selectedSpace = selectedSpaceOption.orNull() + activeSpaceAwareQueries.onEach { updater -> + updater.updateForSpaceId(selectedSpace?.roomId) + } + }.launchIn(viewModelScope) + + return sections + } + + private fun buildRoomsSections( + sections: MutableList, + activeSpaceAwareQueries: MutableList + ) { + if (autoAcceptInvites.showInvites()) { + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.invitations_header, + notifyOfLocalEcho = true, + spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL, + countRoomAsNotif = true + ) { + it.memberships = listOf(Membership.INVITE) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + } + } + + addSection( + sections, + activeSpaceAwareQueries, + R.string.bottom_action_favourites, + false, + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) + } + + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.bottom_action_rooms, + notifyOfLocalEcho = false, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + } + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + it.roomTagQueryFilter = RoomTagQueryFilter(false, false, false) + } + + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.low_priority_header, + notifyOfLocalEcho = false, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + } + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + it.roomTagQueryFilter = RoomTagQueryFilter(null, true, null) + } + + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.system_alerts_header, + notifyOfLocalEcho = false, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + } + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS + it.roomTagQueryFilter = RoomTagQueryFilter(null, null, true) + } + + // add suggested rooms + val suggestedRoomsFlow = // MutableLiveData>() + appStateHandler.selectedSpaceFlow + .distinctUntilChanged() + .flatMapLatest { selectedSpaceOption -> + val selectedSpace = selectedSpaceOption.orNull() + if (selectedSpace == null) { + flowOf(emptyList()) + } else { + liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) { + val spaceSum = tryOrNull { + session.spaceService() + .querySpaceChildren(selectedSpace.roomId, suggestedOnly = true, null, null) + } + val value = spaceSum?.children.orEmpty().distinctBy { it.childRoomId } + // i need to check if it's already joined. + val filtered = value.filter { + session.getRoomSummary(it.childRoomId)?.membership?.isActive() != true + } + emit(filtered) + }.asFlow() + } + } + + val liveSuggestedRooms = MutableLiveData() + combine( + suggestedRoomsFlow, + suggestedRoomJoiningState.asFlow() + ) { rooms, joinStates -> + SuggestedRoomInfo( + rooms, + joinStates + ) + }.onEach { + liveSuggestedRooms.postValue(it) + }.launchIn(viewModelScope) + + sections.add( + RoomsSection( + sectionName = stringProvider.getString(R.string.suggested_header), + liveSuggested = liveSuggestedRooms, + notifyOfLocalEcho = false, + itemCount = suggestedRoomsFlow.map { suggestions -> suggestions.size } + ) + ) + } + + private fun buildDmSections( + sections: MutableList, + activeSpaceAwareQueries: MutableList + ) { + if (autoAcceptInvites.showInvites()) { + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.invitations_header, + notifyOfLocalEcho = true, + spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL, + countRoomAsNotif = true + ) { + it.memberships = listOf(Membership.INVITE) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM + } + } + + addSection( + sections, + activeSpaceAwareQueries, + R.string.bottom_action_favourites, + false, + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM + it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) + } + + addSection( + sections, + activeSpaceAwareQueries, + R.string.bottom_action_people_x, + false, + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM + it.roomTagQueryFilter = RoomTagQueryFilter(false, false, null) + } + + addSection( + sections, + activeSpaceAwareQueries, + R.string.low_priority_header, + false, + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM + it.roomTagQueryFilter = RoomTagQueryFilter(false, true, null) + } + } + + private fun buildNotificationsSection( + sections: MutableList, + activeSpaceAwareQueries: MutableList + ) { + if (autoAcceptInvites.showInvites()) { + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.invitations_header, + notifyOfLocalEcho = true, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + }, + countRoomAsNotif = true + ) { + it.memberships = listOf(Membership.INVITE) + } + } + + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.bottom_action_rooms, + notifyOfLocalEcho = false, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + } + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS + } + } + + private fun buildFilteredSection(sections: MutableList) { + // Used when searching for rooms + withQueryParams( + { + it.memberships = Membership.activeMemberships() + }, + { queryParams -> + val name = stringProvider.getString(R.string.bottom_action_rooms) + val updatableFilterLivePageResult = session.roomService().getFilteredPagedRoomSummariesLive(queryParams, getFlattenParents = true) + onUpdatable(updatableFilterLivePageResult) + + val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() + .flatMapLatest { session.roomService().getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() } + .distinctUntilChanged() + + sections.add( + RoomsSection( + sectionName = name, + livePages = updatableFilterLivePageResult.livePagedList, + itemCount = itemCountFlow + ) + ) + } + ) + } + + private fun addSection( + sections: MutableList, + activeSpaceUpdaters: MutableList, + @StringRes nameRes: Int, + notifyOfLocalEcho: Boolean = false, + spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE, + countRoomAsNotif: Boolean = false, + query: (RoomSummaryQueryParams.Builder) -> Unit + ) { + withQueryParams(query) { roomQueryParams -> + val updatedQueryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) + val liveQueryParams = MutableStateFlow(updatedQueryParams) + val itemCountFlow = liveQueryParams + .flatMapLatest { + session.roomService().getRoomCountLive(it).asFlow() + } + .flowOn(Dispatchers.Main) + .distinctUntilChanged() + + val name = stringProvider.getString(nameRes) + val filteredPagedRoomSummariesLive = session.roomService().getFilteredPagedRoomSummariesLive( + roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()), + pagedListConfig + ) + when (spaceFilterStrategy) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { + activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { + override fun updateForSpaceId(roomId: String?) { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + spaceFilter = roomId?.toActiveSpaceOrOrphanRooms() + ) + liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } + } + }) + } + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { + activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { + override fun updateForSpaceId(roomId: String?) { + if (roomId != null) { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + spaceFilter = SpaceFilter.ActiveSpace(roomId) + ) + } else { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + spaceFilter = null + ) + } + liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } + } + }) + } + RoomListViewModel.SpaceFilterStrategy.NONE -> { + // we ignore current space for this one + } + } + + val livePagedList = filteredPagedRoomSummariesLive.livePagedList + // use it also as a source to update count + livePagedList.asFlow() + .onEach { + Timber.v("Thread space list: ${Thread.currentThread()}") + sections.find { it.sectionName == name } + ?.notificationCount + ?.postValue( + if (countRoomAsNotif) { + RoomAggregateNotificationCount(it.size, it.size) + } else { + session.roomService().getNotificationCountForRooms( + roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) + ) + } + ) + } + .flowOn(Dispatchers.Default) + .launchIn(viewModelScope) + + sections.add( + RoomsSection( + sectionName = name, + livePages = livePagedList, + notifyOfLocalEcho = notifyOfLocalEcho, + itemCount = itemCountFlow + ) + ) + } + } + + private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { + block(roomSummaryQueryParams { builder.invoke(this) }) + } + + internal fun RoomSummaryQueryParams.process(spaceFilter: RoomListViewModel.SpaceFilterStrategy, currentSpace: String?): RoomSummaryQueryParams { + return when (spaceFilter) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { + copy( + spaceFilter = currentSpace?.toActiveSpaceOrOrphanRooms() + ) + } + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { + copy( + spaceFilter = currentSpace?.let { SpaceFilter.ActiveSpace(it) } + ) + } + RoomListViewModel.SpaceFilterStrategy.NONE -> this + } + } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt deleted file mode 100644 index a8a30349c7..0000000000 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2021 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.home.room.list - -import androidx.annotation.StringRes -import androidx.lifecycle.asFlow -import im.vector.app.AppStateHandler -import im.vector.app.R -import im.vector.app.RoomGroupingMethod -import im.vector.app.core.resources.StringProvider -import im.vector.app.features.home.RoomListDisplayMode -import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.invite.showInvites -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.matrix.android.sdk.api.query.RoomCategoryFilter -import org.matrix.android.sdk.api.query.RoomTagQueryFilter -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams -import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams - -class RoomListSectionBuilderGroup( - private val coroutineScope: CoroutineScope, - private val session: Session, - private val stringProvider: StringProvider, - private val appStateHandler: AppStateHandler, - private val autoAcceptInvites: AutoAcceptInvites, - private val onUpdatable: (UpdatableLivePageResult) -> Unit -) : RoomListSectionBuilder { - - override fun buildSections(mode: RoomListDisplayMode): List { - val activeGroupAwareQueries = mutableListOf() - val sections = mutableListOf() - val actualGroupId = appStateHandler.safeActiveGroupId() - - when (mode) { - RoomListDisplayMode.PEOPLE -> { - // 4 sections Invites / Fav / Dms / Low Priority - buildPeopleSections(sections, activeGroupAwareQueries, actualGroupId) - } - RoomListDisplayMode.ROOMS -> { - // 5 sections invites / Fav / Rooms / Low Priority / Server notice - buildRoomsSections(sections, activeGroupAwareQueries, actualGroupId) - } - RoomListDisplayMode.FILTERED -> { - // Used when searching for rooms - withQueryParams( - { - it.memberships = Membership.activeMemberships() - }, - { qpm -> - val name = stringProvider.getString(R.string.bottom_action_rooms) - val updatableFilterLivePageResult = session.roomService().getFilteredPagedRoomSummariesLive(qpm, getFlattenParents = true) - onUpdatable(updatableFilterLivePageResult) - - val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.roomService().getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() } - .distinctUntilChanged() - - sections.add( - RoomsSection( - sectionName = name, - livePages = updatableFilterLivePageResult.livePagedList, - itemCount = itemCountFlow - ) - ) - } - ) - } - RoomListDisplayMode.NOTIFICATIONS -> { - if (autoAcceptInvites.showInvites()) { - addSection( - sections, - activeGroupAwareQueries, - R.string.invitations_header, - true - ) { - it.memberships = listOf(Membership.INVITE) - it.activeGroupId = actualGroupId - } - } - - addSection( - sections, - activeGroupAwareQueries, - R.string.bottom_action_rooms, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS - it.activeGroupId = actualGroupId - } - } - } - - appStateHandler.selectedRoomGroupingFlow - .distinctUntilChanged() - .onEach { groupingMethod -> - val selectedGroupId = (groupingMethod.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId - activeGroupAwareQueries.onEach { updater -> - updater.queryParams = updater.queryParams.copy(activeGroupId = selectedGroupId) - } - }.launchIn(coroutineScope) - - return sections - } - - private fun buildRoomsSections( - sections: MutableList, - activeSpaceAwareQueries: MutableList, - actualGroupId: String? - ) { - if (autoAcceptInvites.showInvites()) { - addSection( - sections, - activeSpaceAwareQueries, - R.string.invitations_header, - true - ) { - it.memberships = listOf(Membership.INVITE) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.activeGroupId = actualGroupId - } - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_favourites, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) - it.activeGroupId = actualGroupId - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_rooms, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(false, false, false) - it.activeGroupId = actualGroupId - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.low_priority_header, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(null, true, null) - it.activeGroupId = actualGroupId - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.system_alerts_header, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(null, null, true) - it.activeGroupId = actualGroupId - } - } - - private fun buildPeopleSections( - sections: MutableList, - activeSpaceAwareQueries: MutableList, - actualGroupId: String? - ) { - if (autoAcceptInvites.showInvites()) { - addSection( - sections, - activeSpaceAwareQueries, - R.string.invitations_header, - true - ) { - it.memberships = listOf(Membership.INVITE) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.activeGroupId = actualGroupId - } - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_favourites, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) - it.activeGroupId = actualGroupId - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_people_x, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(false, false, null) - it.activeGroupId = actualGroupId - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.low_priority_header, - false - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(false, true, null) - it.activeGroupId = actualGroupId - } - } - - private fun addSection( - sections: MutableList, - activeSpaceUpdaters: MutableList, - @StringRes nameRes: Int, - notifyOfLocalEcho: Boolean = false, - query: (RoomSummaryQueryParams.Builder) -> Unit - ) { - withQueryParams(query) { roomQueryParams -> - val name = stringProvider.getString(nameRes) - session.roomService().getFilteredPagedRoomSummariesLive(roomQueryParams) - .also { - activeSpaceUpdaters.add(it) - }.livePagedList - .let { livePagedList -> - // use it also as a source to update count - livePagedList.asFlow() - .onEach { - sections.find { it.sectionName == name } - ?.notificationCount - ?.postValue(session.roomService().getNotificationCountForRooms(roomQueryParams)) - } - .flowOn(Dispatchers.Default) - .launchIn(coroutineScope) - - sections.add( - RoomsSection( - sectionName = name, - livePages = livePagedList, - notifyOfLocalEcho = notifyOfLocalEcho, - itemCount = session.roomService().getRoomCountLive(roomQueryParams).asFlow() - ) - ) - } - } - } - - private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { - block(roomSummaryQueryParams { builder.invoke(this) }) - } -} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt deleted file mode 100644 index 47a1df3ed0..0000000000 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2021 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.home.room.list - -import androidx.annotation.StringRes -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.asFlow -import androidx.lifecycle.liveData -import androidx.paging.PagedList -import com.airbnb.mvrx.Async -import im.vector.app.AppStateHandler -import im.vector.app.R -import im.vector.app.core.resources.StringProvider -import im.vector.app.features.home.RoomListDisplayMode -import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.invite.showInvites -import im.vector.app.space -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.query.RoomCategoryFilter -import org.matrix.android.sdk.api.query.RoomTagQueryFilter -import org.matrix.android.sdk.api.query.SpaceFilter -import org.matrix.android.sdk.api.query.toActiveSpaceOrOrphanRooms -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.getRoomSummary -import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams -import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams -import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount -import timber.log.Timber - -class RoomListSectionBuilderSpace( - private val session: Session, - private val stringProvider: StringProvider, - private val appStateHandler: AppStateHandler, - private val viewModelScope: CoroutineScope, - private val autoAcceptInvites: AutoAcceptInvites, - private val onUpdatable: (UpdatableLivePageResult) -> Unit, - private val suggestedRoomJoiningState: LiveData>>, - private val onlyOrphansInHome: Boolean = false -) : RoomListSectionBuilder { - - private val pagedListConfig = PagedList.Config.Builder() - .setPageSize(10) - .setInitialLoadSizeHint(20) - .setEnablePlaceholders(true) - .setPrefetchDistance(10) - .build() - - override fun buildSections(mode: RoomListDisplayMode): List { - val sections = mutableListOf() - val activeSpaceAwareQueries = mutableListOf() - when (mode) { - RoomListDisplayMode.PEOPLE -> { - // 4 sections Invites / Fav / Dms / Low Priority - buildDmSections(sections, activeSpaceAwareQueries) - } - RoomListDisplayMode.ROOMS -> { - // 6 sections invites / Fav / Rooms / Low Priority / Server notice / Suggested rooms - buildRoomsSections(sections, activeSpaceAwareQueries) - } - RoomListDisplayMode.FILTERED -> { - // Used when searching for rooms - buildFilteredSection(sections) - } - RoomListDisplayMode.NOTIFICATIONS -> { - buildNotificationsSection(sections, activeSpaceAwareQueries) - } - } - - appStateHandler.selectedRoomGroupingFlow - .distinctUntilChanged() - .onEach { groupingMethod -> - val selectedSpace = groupingMethod.orNull()?.space() - activeSpaceAwareQueries.onEach { updater -> - updater.updateForSpaceId(selectedSpace?.roomId) - } - }.launchIn(viewModelScope) - - return sections - } - - private fun buildRoomsSections( - sections: MutableList, - activeSpaceAwareQueries: MutableList - ) { - if (autoAcceptInvites.showInvites()) { - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.invitations_header, - notifyOfLocalEcho = true, - spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL, - countRoomAsNotif = true - ) { - it.memberships = listOf(Membership.INVITE) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - } - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_favourites, - false, - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) - } - - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.bottom_action_rooms, - notifyOfLocalEcho = false, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - } - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(false, false, false) - } - - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.low_priority_header, - notifyOfLocalEcho = false, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - } - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(null, true, null) - } - - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.system_alerts_header, - notifyOfLocalEcho = false, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - } - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS - it.roomTagQueryFilter = RoomTagQueryFilter(null, null, true) - } - - // add suggested rooms - val suggestedRoomsFlow = // MutableLiveData>() - appStateHandler.selectedRoomGroupingFlow - .distinctUntilChanged() - .flatMapLatest { groupingMethod -> - val selectedSpace = groupingMethod.orNull()?.space() - if (selectedSpace == null) { - flowOf(emptyList()) - } else { - liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) { - val spaceSum = tryOrNull { - session.spaceService() - .querySpaceChildren(selectedSpace.roomId, suggestedOnly = true, null, null) - } - val value = spaceSum?.children.orEmpty().distinctBy { it.childRoomId } - // i need to check if it's already joined. - val filtered = value.filter { - session.getRoomSummary(it.childRoomId)?.membership?.isActive() != true - } - emit(filtered) - }.asFlow() - } - } - - val liveSuggestedRooms = MutableLiveData() - combine( - suggestedRoomsFlow, - suggestedRoomJoiningState.asFlow() - ) { rooms, joinStates -> - SuggestedRoomInfo( - rooms, - joinStates - ) - }.onEach { - liveSuggestedRooms.postValue(it) - }.launchIn(viewModelScope) - - sections.add( - RoomsSection( - sectionName = stringProvider.getString(R.string.suggested_header), - liveSuggested = liveSuggestedRooms, - notifyOfLocalEcho = false, - itemCount = suggestedRoomsFlow.map { suggestions -> suggestions.size } - ) - ) - } - - private fun buildDmSections( - sections: MutableList, - activeSpaceAwareQueries: MutableList - ) { - if (autoAcceptInvites.showInvites()) { - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.invitations_header, - notifyOfLocalEcho = true, - spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL, - countRoomAsNotif = true - ) { - it.memberships = listOf(Membership.INVITE) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - } - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_favourites, - false, - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null) - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.bottom_action_people_x, - false, - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(false, false, null) - } - - addSection( - sections, - activeSpaceAwareQueries, - R.string.low_priority_header, - false, - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM - it.roomTagQueryFilter = RoomTagQueryFilter(false, true, null) - } - } - - private fun buildNotificationsSection( - sections: MutableList, - activeSpaceAwareQueries: MutableList - ) { - if (autoAcceptInvites.showInvites()) { - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.invitations_header, - notifyOfLocalEcho = true, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - }, - countRoomAsNotif = true - ) { - it.memberships = listOf(Membership.INVITE) - } - } - - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.bottom_action_rooms, - notifyOfLocalEcho = false, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - } - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS - } - } - - private fun buildFilteredSection(sections: MutableList) { - // Used when searching for rooms - withQueryParams( - { - it.memberships = Membership.activeMemberships() - }, - { queryParams -> - val name = stringProvider.getString(R.string.bottom_action_rooms) - val updatableFilterLivePageResult = session.roomService().getFilteredPagedRoomSummariesLive(queryParams, getFlattenParents = true) - onUpdatable(updatableFilterLivePageResult) - - val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.roomService().getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() } - .distinctUntilChanged() - - sections.add( - RoomsSection( - sectionName = name, - livePages = updatableFilterLivePageResult.livePagedList, - itemCount = itemCountFlow - ) - ) - } - ) - } - - private fun addSection( - sections: MutableList, - activeSpaceUpdaters: MutableList, - @StringRes nameRes: Int, - notifyOfLocalEcho: Boolean = false, - spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE, - countRoomAsNotif: Boolean = false, - query: (RoomSummaryQueryParams.Builder) -> Unit - ) { - withQueryParams(query) { roomQueryParams -> - val updatedQueryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) - val liveQueryParams = MutableStateFlow(updatedQueryParams) - val itemCountFlow = liveQueryParams - .flatMapLatest { - session.roomService().getRoomCountLive(it).asFlow() - } - .flowOn(Dispatchers.Main) - .distinctUntilChanged() - - val name = stringProvider.getString(nameRes) - val filteredPagedRoomSummariesLive = session.roomService().getFilteredPagedRoomSummariesLive( - roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()), - pagedListConfig - ) - when (spaceFilterStrategy) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { - activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { - override fun updateForSpaceId(roomId: String?) { - filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( - spaceFilter = roomId.toActiveSpaceOrOrphanRooms() - ) - liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } - } - }) - } - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { - activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { - override fun updateForSpaceId(roomId: String?) { - if (roomId != null) { - filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( - spaceFilter = SpaceFilter.ActiveSpace(roomId) - ) - } else { - filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( - spaceFilter = null - ) - } - liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } - } - }) - } - RoomListViewModel.SpaceFilterStrategy.NONE -> { - // we ignore current space for this one - } - } - - val livePagedList = filteredPagedRoomSummariesLive.livePagedList - // use it also as a source to update count - livePagedList.asFlow() - .onEach { - Timber.v("Thread space list: ${Thread.currentThread()}") - sections.find { it.sectionName == name } - ?.notificationCount - ?.postValue( - if (countRoomAsNotif) { - RoomAggregateNotificationCount(it.size, it.size) - } else { - session.roomService().getNotificationCountForRooms( - roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) - ) - } - ) - } - .flowOn(Dispatchers.Default) - .launchIn(viewModelScope) - - sections.add( - RoomsSection( - sectionName = name, - livePages = livePagedList, - notifyOfLocalEcho = notifyOfLocalEcho, - itemCount = itemCountFlow - ) - ) - } - } - - private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { - block(roomSummaryQueryParams { builder.invoke(this) }) - } - - internal fun RoomSummaryQueryParams.process(spaceFilter: RoomListViewModel.SpaceFilterStrategy, currentSpace: String?): RoomSummaryQueryParams { - return when (spaceFilter) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { - copy( - spaceFilter = currentSpace.toActiveSpaceOrOrphanRooms() - ) - } - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { - copy( - spaceFilter = currentSpace?.let { SpaceFilter.ActiveSpace(it) } - ) - } - RoomListViewModel.SpaceFilterStrategy.NONE -> this - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index cd4bb06949..44d61f9ed2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -26,7 +26,6 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel @@ -101,11 +100,11 @@ class RoomListViewModel @AssistedInject constructor( observeMembershipChanges() observeLocalRooms() - appStateHandler.selectedRoomGroupingFlow + appStateHandler.selectedSpaceFlow .distinctUntilChanged() .execute { copy( - currentRoomGrouping = it.invoke()?.orNull()?.let { Success(it) } ?: Loading() + asyncSelectedSpace = it.invoke()?.orNull()?.let { Success(it) } ?: Loading() ) } @@ -146,8 +145,7 @@ class RoomListViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() - private val roomListSectionBuilder = if (appStateHandler.getCurrentRoomGroupingMethod() is RoomGroupingMethod.BySpace) { - RoomListSectionBuilderSpace( + private val roomListSectionBuilder = RoomListSectionBuilder( session, stringProvider, appStateHandler, @@ -159,17 +157,6 @@ class RoomListViewModel @AssistedInject constructor( suggestedRoomJoiningState, !vectorPreferences.prefSpacesShowAllRoomInHome() ) - } else { - RoomListSectionBuilderGroup( - viewModelScope, - session, - stringProvider, - appStateHandler, - autoAcceptInvites - ) { - updatableQuery = it - } - } val sections: List by lazy { roomListSectionBuilder.buildSections(initialState.displayMode) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt index 9d386b679a..3f46293346 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt @@ -19,9 +19,9 @@ package im.vector.app.features.home.room.list import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized -import im.vector.app.RoomGroupingMethod import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo data class RoomListViewState( @@ -30,7 +30,7 @@ data class RoomListViewState( val roomMembershipChanges: Map = emptyMap(), val asyncSuggestedRooms: Async> = Uninitialized, val currentUserName: String? = null, - val currentRoomGrouping: Async = Uninitialized, + val asyncSelectedSpace: Async = Uninitialized, val localRoomIds: Set = emptySet() ) : MavericksState { diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index 13a33cf30d..5f20b7278e 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -94,7 +94,6 @@ class PillsPostProcessor @AssistedInject constructor( val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) { is PermalinkData.UserLink -> permalinkData.toMatrixItem(roomId) is PermalinkData.RoomLink -> permalinkData.toMatrixItem() - is PermalinkData.GroupLink -> permalinkData.toMatrixItem() else -> null } ?: return null return createPillImageSpan(matrixItem) @@ -118,9 +117,4 @@ class PillsPostProcessor @AssistedInject constructor( // Exclude event link (used in reply events, we do not want to pill the "in reply to") null } - - private fun PermalinkData.GroupLink.toMatrixItem(): MatrixItem? { - val group = sessionHolder.getSafeActiveSession()?.groupService()?.getGroupSummary(groupId) - return MatrixItem.GroupItem(groupId, group?.displayName, group?.avatarUrl) - } } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 8e4699aa0f..97a993d4d3 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -75,8 +75,7 @@ class MatrixToBottomSheet : views.matrixToCardContentLoading.isVisible = state.matrixItem is Incomplete showFragment(MatrixToUserFragment::class, Bundle()) } - is PermalinkData.GroupLink -> Unit - is PermalinkData.FallbackLink -> Unit + is PermalinkData.FallbackLink, is PermalinkData.RoomEmailInviteLink -> Unit } } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index 67bc245014..24a623160e 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -76,13 +76,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( copy(matrixItem = Loading()) } } - is PermalinkData.GroupLink -> { - // Not yet supported - } - is PermalinkData.FallbackLink -> { - // Not yet supported - } - is PermalinkData.RoomEmailInviteLink -> Unit + is PermalinkData.RoomEmailInviteLink, + is PermalinkData.FallbackLink -> Unit } viewModelScope.launch(Dispatchers.IO) { resolveLink(initialState) @@ -186,10 +181,6 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( } } } - is PermalinkData.GroupLink -> { - // not yet supported - _viewEvents.post(MatrixToViewEvents.Dismiss) - } is PermalinkData.RoomEmailInviteLink, is PermalinkData.FallbackLink -> { _viewEvents.post(MatrixToViewEvents.Dismiss) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 2de01a5531..291eee307f 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -23,6 +23,7 @@ import android.net.Uri import android.os.Build import android.view.View import android.view.Window +import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityOptionsCompat @@ -32,11 +33,8 @@ import androidx.core.view.ViewCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.AppStateHandler import im.vector.app.R -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.error.fatalError -import im.vector.app.core.platform.VectorBaseActivity -import im.vector.app.core.utils.toast import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures.OnboardingVariant import im.vector.app.features.analytics.AnalyticsTracker @@ -105,11 +103,11 @@ import im.vector.app.features.spaces.people.SpacePeopleActivity import im.vector.app.features.terms.ReviewTermsActivity import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder -import im.vector.app.space import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.permalinks.PermalinkData +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.widgets.model.Widget @@ -169,7 +167,7 @@ class DefaultNavigator @Inject constructor( analyticsTracker.capture( sessionHolder.getActiveSession().getRoomSummary(roomId).toAnalyticsViewRoom( trigger = trigger, - groupingMethod = appStateHandler.getCurrentRoomGroupingMethod() + selectedSpace = appStateHandler.getCurrentSpace() ) ) } @@ -284,14 +282,6 @@ class DefaultNavigator @Inject constructor( } } - override fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean) { - if (context is VectorBaseActivity<*>) { - context.notImplemented("Open group detail") - } else { - context.toast(R.string.not_implemented) - } - } - override fun openRoomMemberProfile(userId: String, roomId: String?, context: Context, buildTask: Boolean) { val args = RoomMemberProfileArgs(userId = userId, roomId = roomId) val intent = RoomMemberProfileActivity.newIntent(context, args) @@ -328,25 +318,10 @@ class DefaultNavigator @Inject constructor( } override fun openRoomDirectory(context: Context, initialFilter: String) { - when (val groupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.ByLegacyGroup -> { - // TODO should open list of rooms of this group - val intent = RoomDirectoryActivity.getIntent(context, initialFilter) - context.startActivity(intent) - } - is RoomGroupingMethod.BySpace -> { - val selectedSpace = groupingMethod.space() - if (selectedSpace == null) { - val intent = RoomDirectoryActivity.getIntent(context, initialFilter) - context.startActivity(intent) - } else { - SpaceExploreActivity.newIntent(context, selectedSpace.roomId).let { - context.startActivity(it) - } - } - } - null -> Unit - } + when (val currentSpace = appStateHandler.getCurrentSpace()) { + null -> RoomDirectoryActivity.getIntent(context, initialFilter) + else -> SpaceExploreActivity.newIntent(context, currentSpace.roomId) + }.start(context) } override fun openCreateRoom(context: Context, initialName: String, openAfterCreate: Boolean) { @@ -355,54 +330,24 @@ class DefaultNavigator @Inject constructor( } override fun openCreateDirectRoom(context: Context) { - val intent = when (val currentGroupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.ByLegacyGroup -> { - CreateDirectRoomActivity.getIntent(context) - } - is RoomGroupingMethod.BySpace -> { - if (currentGroupingMethod.spaceSummary != null) { - SpacePeopleActivity.newIntent(context, currentGroupingMethod.spaceSummary.roomId) - } else { - CreateDirectRoomActivity.getIntent(context) - } - } - else -> null - } ?: return - context.startActivity(intent) + when (val currentSpace = appStateHandler.getCurrentSpace()) { + null -> CreateDirectRoomActivity.getIntent(context) + else -> SpacePeopleActivity.newIntent(context, currentSpace.roomId) + }.start(context) } override fun openInviteUsersToRoom(context: Context, roomId: String) { - when (val currentGroupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.ByLegacyGroup -> { - val intent = InviteUsersToRoomActivity.getIntent(context, roomId) - context.startActivity(intent) - } - is RoomGroupingMethod.BySpace -> { - if (currentGroupingMethod.spaceSummary != null) { - // let user decides if he does it from space or room - (context as? AppCompatActivity)?.supportFragmentManager?.let { fm -> - InviteRoomSpaceChooserBottomSheet.newInstance( - currentGroupingMethod.spaceSummary.roomId, - roomId, - object : InviteRoomSpaceChooserBottomSheet.InteractionListener { - override fun inviteToSpace(spaceId: String) { - val intent = InviteUsersToRoomActivity.getIntent(context, spaceId) - context.startActivity(intent) - } + when (val currentSpace = appStateHandler.getCurrentSpace()) { + null -> InviteUsersToRoomActivity.getIntent(context, roomId).start(context) + else -> showInviteToDialog(context, currentSpace, roomId) + } + } - override fun inviteToRoom(roomId: String) { - val intent = InviteUsersToRoomActivity.getIntent(context, roomId) - context.startActivity(intent) - } - } - ).show(fm, InviteRoomSpaceChooserBottomSheet::class.java.name) - } - } else { - val intent = InviteUsersToRoomActivity.getIntent(context, roomId) - context.startActivity(intent) - } + private fun showInviteToDialog(context: Context, currentSpace: RoomSummary, roomId: String) { + (context as? AppCompatActivity)?.supportFragmentManager?.let { fragmentManager -> + InviteRoomSpaceChooserBottomSheet.showInstance(fragmentManager, currentSpace.roomId, roomId) { itemId -> + InviteUsersToRoomActivity.getIntent(context, itemId).start(context) } - null -> Unit } } @@ -449,6 +394,10 @@ class DefaultNavigator @Inject constructor( context.startActivity(KeysBackupManageActivity.intent(context)) } + override fun showGroupsUnsupportedWarning(context: Context) { + Toast.makeText(context, context.getString(R.string.permalink_unsupported_groups), Toast.LENGTH_LONG).show() + } + override fun openRoomProfile(context: Context, roomId: String, directAccess: Int?) { context.startActivity(RoomProfileActivity.newIntent(context, roomId, directAccess)) } @@ -658,4 +607,8 @@ class DefaultNavigator @Inject constructor( ) { activityResultLauncher.launch(screenCaptureIntent) } + + private fun Intent.start(context: Context) { + context.startActivity(this) + } } diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 7b6a81db52..7410d412c2 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -112,7 +112,7 @@ interface Navigator { fun openKeysBackupManager(context: Context) - fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean = false) + fun showGroupsUnsupportedWarning(context: Context) fun openRoomMemberProfile(userId: String, roomId: String?, context: Context, buildTask: Boolean = false) 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 cd75fd5036..fc56891b72 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 @@ -90,55 +90,84 @@ class PermalinkHandler @Inject constructor( buildTask: Boolean ): Boolean { return when (permalinkData) { - is PermalinkData.RoomLink -> { - val roomId = permalinkData.getRoomId() - val session = activeSessionHolder.getSafeActiveSession() + is PermalinkData.RoomLink -> handleRoomLink(permalinkData, rawLink, context, navigationInterceptor, buildTask) + is PermalinkData.UserLink -> handleUserLink(permalinkData, rawLink, context, navigationInterceptor, buildTask) + is PermalinkData.FallbackLink -> handleFallbackLink(permalinkData, context) + is PermalinkData.RoomEmailInviteLink -> handleRoomInviteLink(permalinkData, context) + } + } - val rootThreadEventId = permalinkData.eventId?.let { eventId -> - val room = roomId?.let { session?.getRoom(it) } + private suspend fun handleRoomLink( + permalinkData: PermalinkData.RoomLink, + rawLink: Uri, + context: Context, + navigationInterceptor: NavigationInterceptor?, + buildTask: Boolean + ): Boolean { + val roomId = permalinkData.getRoomId() + val session = activeSessionHolder.getSafeActiveSession() - val rootThreadEventId = room?.getTimelineEvent(eventId)?.root?.getRootThreadEventId() - rootThreadEventId ?: if (room?.getTimelineEvent(eventId)?.isRootThread() == true) { - eventId - } else { - null - } - } - openRoom( - navigationInterceptor, - context = context, - roomId = roomId, - permalinkData = permalinkData, - rawLink = rawLink, - buildTask = buildTask, - rootThreadEventId = rootThreadEventId - ) - true + val rootThreadEventId = permalinkData.eventId?.let { eventId -> + val room = roomId?.let { session?.getRoom(it) } + + val rootThreadEventId = room?.getTimelineEvent(eventId)?.root?.getRootThreadEventId() + rootThreadEventId ?: if (room?.getTimelineEvent(eventId)?.isRootThread() == true) { + eventId + } else { + null } - is PermalinkData.GroupLink -> { - navigator.openGroupDetail(permalinkData.groupId, context, buildTask) - true - } - is PermalinkData.UserLink -> { - if (navigationInterceptor?.navToMemberProfile(permalinkData.userId, rawLink) != true) { - navigator.openRoomMemberProfile(userId = permalinkData.userId, roomId = null, context = context, buildTask = buildTask) - } - true - } - is PermalinkData.FallbackLink -> { - false - } - is PermalinkData.RoomEmailInviteLink -> { - val data = RoomPreviewData( - roomId = permalinkData.roomId, - roomName = permalinkData.roomName, - avatarUrl = permalinkData.roomAvatarUrl, - fromEmailInvite = permalinkData, - roomType = permalinkData.roomType - ) - navigator.openRoomPreview(context, data) - true + } + openRoom( + navigationInterceptor, + context = context, + roomId = roomId, + permalinkData = permalinkData, + rawLink = rawLink, + buildTask = buildTask, + rootThreadEventId = rootThreadEventId + ) + return true + } + + private fun handleUserLink( + permalinkData: PermalinkData.UserLink, + rawLink: Uri, + context: Context, + navigationInterceptor: NavigationInterceptor?, + buildTask: Boolean + ): Boolean { + if (navigationInterceptor?.navToMemberProfile(permalinkData.userId, rawLink) != true) { + navigator.openRoomMemberProfile(userId = permalinkData.userId, roomId = null, context = context, buildTask = buildTask) + } + return true + } + + private fun handleRoomInviteLink( + permalinkData: PermalinkData.RoomEmailInviteLink, + context: Context + ): Boolean { + val data = RoomPreviewData( + roomId = permalinkData.roomId, + roomName = permalinkData.roomName, + avatarUrl = permalinkData.roomAvatarUrl, + fromEmailInvite = permalinkData, + roomType = permalinkData.roomType + ) + navigator.openRoomPreview(context, data) + return true + } + + private suspend fun handleFallbackLink( + permalinkData: PermalinkData.FallbackLink, + context: Context + ): Boolean { + return if (permalinkData.isLegacyGroupLink) { + withContext(Dispatchers.Main) { + navigator.showGroupsUnsupportedWarning(context) } + true + } else { + false } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt index b4c1e67cfb..702bdc2a8f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt @@ -22,6 +22,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.fragment.app.FragmentManager import com.airbnb.mvrx.args import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R @@ -47,12 +48,7 @@ class InviteRoomSpaceChooserBottomSheet : VectorBaseBottomSheetDialogFragment Unit)? = null override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetSpaceInviteChooserBinding { return BottomSheetSpaceInviteChooserBinding.inflate(inflater, container, false) @@ -72,7 +68,7 @@ class InviteRoomSpaceChooserBottomSheet : VectorBaseBottomSheetDialogFragment Unit + ) { + InviteRoomSpaceChooserBottomSheet().apply { + this.onItemSelected = onItemSelected setArguments(Args(spaceId, roomId)) - } + }.show(fragmentManager, InviteRoomSpaceChooserBottomSheet::class.java.name) } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt index 5bff2b733f..fd2e68e172 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt @@ -17,7 +17,6 @@ package im.vector.app.features.spaces import im.vector.app.core.platform.VectorViewModelAction -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary sealed class SpaceListAction : VectorViewModelAction { @@ -29,6 +28,4 @@ sealed class SpaceListAction : VectorViewModelAction { data class MoveSpace(val spaceId: String, val delta: Int) : SpaceListAction() data class OnStartDragging(val spaceId: String, val expanded: Boolean) : SpaceListAction() data class OnEndDragging(val spaceId: String, val expanded: Boolean) : SpaceListAction() - - data class SelectLegacyGroup(val groupSummary: GroupSummary?) : SpaceListAction() } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt index 29742bb290..ad131cbd57 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt @@ -34,7 +34,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGroupListBinding import im.vector.app.features.home.HomeActivitySharedAction import im.vector.app.features.home.HomeSharedActionViewModel -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject @@ -76,19 +75,16 @@ class SpaceListFragment @Inject constructor( } override fun onDragReleased(model: SpaceSummaryItem?, itemView: View?) { -// Timber.v("VAL: onModelMoved from $fromPositionM to $toPositionM ${model?.matrixItem?.getBestName()}") if (toPositionM == null || fromPositionM == null) return val movingSpace = model?.matrixItem?.id ?: return viewModel.handle(SpaceListAction.MoveSpace(movingSpace, toPositionM!! - fromPositionM!!)) } override fun clearView(model: SpaceSummaryItem?, itemView: View?) { -// Timber.v("VAL: clearView ${model?.matrixItem?.getBestName()}") itemView?.elevation = initialElevation ?: 0f } override fun onModelMoved(fromPosition: Int, toPosition: Int, modelBeingMoved: SpaceSummaryItem?, itemView: View?) { -// Timber.v("VAL: onModelMoved incremental from $fromPosition to $toPosition ${modelBeingMoved?.matrixItem?.getBestName()}") if (fromPositionM == null) { fromPositionM = fromPosition } @@ -97,7 +93,6 @@ class SpaceListFragment @Inject constructor( } override fun isDragEnabledForModel(model: SpaceSummaryItem?): Boolean { -// Timber.v("VAL: isDragEnabledForModel ${model?.matrixItem?.getBestName()}") return model?.canDrag == true } }) @@ -105,10 +100,9 @@ class SpaceListFragment @Inject constructor( viewModel.observeViewEvents { when (it) { is SpaceListViewEvents.OpenSpaceSummary -> sharedActionViewModel.post(HomeActivitySharedAction.OpenSpacePreview(it.id)) - is SpaceListViewEvents.OpenSpace -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup(it.groupingMethodHasChanged)) is SpaceListViewEvents.AddSpace -> sharedActionViewModel.post(HomeActivitySharedAction.AddSpace) - is SpaceListViewEvents.OpenGroup -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup(it.groupingMethodHasChanged)) is SpaceListViewEvents.OpenSpaceInvite -> sharedActionViewModel.post(HomeActivitySharedAction.OpenSpaceInvite(it.id)) + SpaceListViewEvents.CloseDrawer -> sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) } } } @@ -149,10 +143,6 @@ class SpaceListFragment @Inject constructor( viewModel.handle(SpaceListAction.AddSpace) } - override fun onGroupSelected(groupSummary: GroupSummary?) { - viewModel.handle(SpaceListAction.SelectLegacyGroup(groupSummary)) - } - override fun sendFeedBack() { sharedActionViewModel.post(HomeActivitySharedAction.SendSpaceFeedBack) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewEvents.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewEvents.kt index afc72b188d..bddd7c3c3d 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewEvents.kt @@ -22,9 +22,8 @@ import im.vector.app.core.platform.VectorViewEvents * Transient events for group list screen. */ sealed class SpaceListViewEvents : VectorViewEvents { - data class OpenSpace(val groupingMethodHasChanged: Boolean) : SpaceListViewEvents() data class OpenSpaceSummary(val id: String) : SpaceListViewEvents() data class OpenSpaceInvite(val id: String) : SpaceListViewEvents() object AddSpace : SpaceListViewEvents() - data class OpenGroup(val groupingMethodHasChanged: Boolean) : SpaceListViewEvents() + object CloseDrawer : SpaceListViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 16cc2d21f4..3b2fb31b74 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -24,7 +24,6 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler -import im.vector.app.RoomGroupingMethod import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel @@ -33,8 +32,6 @@ import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorPreferences -import im.vector.app.group -import im.vector.app.space import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -50,7 +47,6 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.getRoom -import org.matrix.android.sdk.api.session.group.groupSummaryQueryParams import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership @@ -79,10 +75,7 @@ class SpaceListViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() -// private var currentGroupingMethod : RoomGroupingMethod? = null - init { - session.userService().getUserLive(session.myUserId) .asFlow() .setOnEach { @@ -93,20 +86,14 @@ class SpaceListViewModel @AssistedInject constructor( observeSpaceSummaries() // observeSelectionState() - appStateHandler.selectedRoomGroupingFlow + appStateHandler.selectedSpaceFlow .distinctUntilChanged() - .setOnEach { + .setOnEach { selectedSpaceOption -> copy( - selectedGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) + selectedSpace = selectedSpaceOption.orNull() ) } - session.groupService().getGroupSummariesLive(groupSummaryQueryParams {}) - .asFlow() - .setOnEach { - copy(legacyGroups = it) - } - // XXX there should be a way to refactor this and share it session.roomService().getPagedRoomSummariesLive( roomSummaryQueryParams { @@ -154,7 +141,6 @@ class SpaceListViewModel @AssistedInject constructor( SpaceListAction.AddSpace -> handleAddSpace() is SpaceListAction.ToggleExpand -> handleToggleExpand(action) is SpaceListAction.OpenSpaceInvite -> handleSelectSpaceInvite(action) - is SpaceListAction.SelectLegacyGroup -> handleSelectGroup(action) is SpaceListAction.MoveSpace -> handleMoveSpace(action) is SpaceListAction.OnEndDragging -> handleEndDragging() is SpaceListAction.OnStartDragging -> handleStartDragging() @@ -229,26 +215,16 @@ class SpaceListViewModel @AssistedInject constructor( } private fun handleSelectSpace(action: SpaceListAction.SelectSpace) = withState { state -> - val groupingMethod = state.selectedGroupingMethod - if (groupingMethod is RoomGroupingMethod.ByLegacyGroup || groupingMethod.space()?.roomId != action.spaceSummary?.roomId) { + if (state.selectedSpace?.roomId != action.spaceSummary?.roomId) { analyticsTracker.capture(Interaction(null, null, Interaction.Name.SpacePanelSwitchSpace)) - setState { copy(selectedGroupingMethod = RoomGroupingMethod.BySpace(action.spaceSummary)) } + setState { copy(selectedSpace = action.spaceSummary) } appStateHandler.setCurrentSpace(action.spaceSummary?.roomId) - _viewEvents.post(SpaceListViewEvents.OpenSpace(groupingMethod is RoomGroupingMethod.ByLegacyGroup)) + _viewEvents.post(SpaceListViewEvents.CloseDrawer) } else { analyticsTracker.capture(Interaction(null, null, Interaction.Name.SpacePanelSelectedSpace)) } } - private fun handleSelectGroup(action: SpaceListAction.SelectLegacyGroup) = withState { state -> - val groupingMethod = state.selectedGroupingMethod - if (groupingMethod is RoomGroupingMethod.BySpace || groupingMethod.group()?.groupId != action.groupSummary?.groupId) { - setState { copy(selectedGroupingMethod = RoomGroupingMethod.ByLegacyGroup(action.groupSummary)) } - appStateHandler.setCurrentGroup(action.groupSummary?.groupId) - _viewEvents.post(SpaceListViewEvents.OpenGroup(groupingMethod is RoomGroupingMethod.BySpace)) - } - } - private fun handleSelectSpaceInvite(action: SpaceListAction.OpenSpaceInvite) { _viewEvents.post(SpaceListViewEvents.OpenSpaceInvite(action.spaceSummary.roomId)) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt index eafc6a241e..794f1dbd69 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt @@ -19,8 +19,6 @@ package im.vector.app.features.spaces import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized -import im.vector.app.RoomGroupingMethod -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.api.util.MatrixItem @@ -28,11 +26,10 @@ import org.matrix.android.sdk.api.util.MatrixItem data class SpaceListViewState( val myMxItem: Async = Uninitialized, val asyncSpaces: Async> = Uninitialized, - val selectedGroupingMethod: RoomGroupingMethod = RoomGroupingMethod.BySpace(null), + val selectedSpace: RoomSummary? = null, val rootSpacesOrdered: List? = null, val spaceOrderInfo: Map? = null, val spaceOrderLocalEchos: Map? = null, - val legacyGroups: List? = null, val expandedStates: Map = emptyMap(), val homeAggregateCount: RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0) ) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt index 302676a27c..233e33af18 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt @@ -18,20 +18,11 @@ package im.vector.app.features.spaces import com.airbnb.epoxy.EpoxyController import im.vector.app.R -import im.vector.app.RoomGroupingMethod -import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider -import im.vector.app.core.ui.list.genericFooterItem -import im.vector.app.core.ui.list.genericHeaderItem -import im.vector.app.features.grouplist.groupSummaryItem import im.vector.app.features.grouplist.homeSpaceSummaryItem import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.list.UnreadCounterBadgeView -import im.vector.app.group -import im.vector.app.space -import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo @@ -41,7 +32,6 @@ import javax.inject.Inject class SpaceSummaryController @Inject constructor( private val avatarRenderer: AvatarRenderer, - private val colorProvider: ColorProvider, private val stringProvider: StringProvider, ) : EpoxyController() { @@ -57,59 +47,18 @@ class SpaceSummaryController @Inject constructor( override fun buildModels() { val nonNullViewState = viewState ?: return - val host = this buildGroupModels( nonNullViewState.asyncSpaces(), - nonNullViewState.selectedGroupingMethod, + nonNullViewState.selectedSpace, nonNullViewState.rootSpacesOrdered, nonNullViewState.expandedStates, nonNullViewState.homeAggregateCount ) - - if (!nonNullViewState.legacyGroups.isNullOrEmpty()) { - genericFooterItem { - id("legacy_space") - text(" ".toEpoxyCharSequence()) - } - - genericHeaderItem { - id("legacy_groups") - text(host.stringProvider.getString(R.string.groups_header)) - textColor(host.colorProvider.getColorFromAttribute(R.attr.vctr_content_primary)) - } - - // add home for communities - nonNullViewState.myMxItem.invoke()?.let { mxItem -> - groupSummaryItem { - avatarRenderer(host.avatarRenderer) - id("all_communities") - matrixItem(mxItem.copy(displayName = host.stringProvider.getString(R.string.group_all_communities))) - selected( - nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup && - nonNullViewState.selectedGroupingMethod.group() == null - ) - listener { host.callback?.onGroupSelected(null) } - } - } - - nonNullViewState.legacyGroups.forEach { groupSummary -> - groupSummaryItem { - avatarRenderer(host.avatarRenderer) - id(groupSummary.groupId) - matrixItem(groupSummary.toMatrixItem()) - selected( - nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup && - nonNullViewState.selectedGroupingMethod.group()?.groupId == groupSummary.groupId - ) - listener { host.callback?.onGroupSelected(groupSummary) } - } - } - } } private fun buildGroupModels( summaries: List?, - selected: RoomGroupingMethod, + selectedSpace: RoomSummary?, rootSpaces: List?, expandedStates: Map, homeCount: RoomAggregateNotificationCount @@ -137,7 +86,7 @@ class SpaceSummaryController @Inject constructor( homeSpaceSummaryItem { id("space_home") - selected(selected is RoomGroupingMethod.BySpace && selected.space() == null) + selected(selectedSpace == null) countState(UnreadCounterBadgeView.State(homeCount.totalCount, homeCount.isHighlight)) listener { host.callback?.onSpaceSelected(null) } } @@ -145,7 +94,7 @@ class SpaceSummaryController @Inject constructor( rootSpaces ?.filter { it.membership != Membership.INVITE } ?.forEach { roomSummary -> - val isSelected = selected is RoomGroupingMethod.BySpace && roomSummary.roomId == selected.space()?.roomId + val isSelected = roomSummary.roomId == selectedSpace?.roomId // does it have children? val subSpaces = roomSummary.spaceChildren?.filter { childInfo -> summaries?.any { it.roomId == childInfo.childRoomId }.orFalse() @@ -178,7 +127,7 @@ class SpaceSummaryController @Inject constructor( if (hasChildren && expanded) { // it's expanded subSpaces?.forEach { child -> - buildSubSpace(roomSummary.roomId, summaries, expandedStates, selected, child, 1, 3) + buildSubSpace(roomSummary.roomId, summaries, expandedStates, selectedSpace, child, 1, 3) } } } @@ -193,7 +142,7 @@ class SpaceSummaryController @Inject constructor( idPrefix: String, summaries: List?, expandedStates: Map, - selected: RoomGroupingMethod, + selectedSpace: RoomSummary?, info: SpaceChildInfo, currentDepth: Int, maxDepth: Int ) { val host = this @@ -204,7 +153,7 @@ class SpaceSummaryController @Inject constructor( summaries.any { it.roomId == childInfo.childRoomId } }?.sortedWith(subSpaceComparator) val expanded = expandedStates[childSummary.roomId] == true - val isSelected = selected is RoomGroupingMethod.BySpace && childSummary.roomId == selected.space()?.roomId + val isSelected = childSummary.roomId == selectedSpace?.roomId val id = "$idPrefix:${childSummary.roomId}" @@ -229,7 +178,7 @@ class SpaceSummaryController @Inject constructor( if (expanded) { subSpaces?.forEach { - buildSubSpace(id, summaries, expandedStates, selected, it, currentDepth + 1, maxDepth) + buildSubSpace(id, summaries, expandedStates, selectedSpace, it, currentDepth + 1, maxDepth) } } } @@ -240,7 +189,6 @@ class SpaceSummaryController @Inject constructor( fun onSpaceSettings(spaceSummary: RoomSummary) fun onToggleExpand(spaceSummary: RoomSummary) fun onAddSpaceSelected() - fun onGroupSelected(groupSummary: GroupSummary?) fun sendFeedBack() } } diff --git a/vector/src/main/java/im/vector/app/features/ui/SharedPreferencesUiStateRepository.kt b/vector/src/main/java/im/vector/app/features/ui/SharedPreferencesUiStateRepository.kt index 22abea15b0..e1bac6ab63 100644 --- a/vector/src/main/java/im/vector/app/features/ui/SharedPreferencesUiStateRepository.kt +++ b/vector/src/main/java/im/vector/app/features/ui/SharedPreferencesUiStateRepository.kt @@ -67,30 +67,10 @@ class SharedPreferencesUiStateRepository @Inject constructor( } } - override fun storeSelectedGroup(groupId: String?, sessionId: String) { - sharedPreferences.edit { - putString("$KEY_SELECTED_GROUP@$sessionId", groupId) - } - } - - override fun storeGroupingMethod(isSpace: Boolean, sessionId: String) { - sharedPreferences.edit { - putBoolean("$KEY_SELECTED_METHOD@$sessionId", isSpace) - } - } - - override fun getSelectedGroup(sessionId: String): String? { - return sharedPreferences.getString("$KEY_SELECTED_GROUP@$sessionId", null) - } - override fun getSelectedSpace(sessionId: String): String? { return sharedPreferences.getString("$KEY_SELECTED_SPACE@$sessionId", null) } - override fun isGroupingMethodSpace(sessionId: String): Boolean { - return sharedPreferences.getBoolean("$KEY_SELECTED_METHOD@$sessionId", true) - } - override fun setCustomRoomDirectoryHomeservers(sessionId: String, servers: Set) { sharedPreferences.edit { putStringSet("$KEY_CUSTOM_DIRECTORY_HOMESERVER@$sessionId", servers) @@ -110,8 +90,6 @@ class SharedPreferencesUiStateRepository @Inject constructor( private const val VALUE_DISPLAY_MODE_ROOMS = 2 private const val KEY_SELECTED_SPACE = "UI_STATE_SELECTED_SPACE" - private const val KEY_SELECTED_GROUP = "UI_STATE_SELECTED_GROUP" - private const val KEY_SELECTED_METHOD = "UI_STATE_SELECTED_METHOD" private const val KEY_CUSTOM_DIRECTORY_HOMESERVER = "KEY_CUSTOM_DIRECTORY_HOMESERVER" } diff --git a/vector/src/main/java/im/vector/app/features/ui/UiStateRepository.kt b/vector/src/main/java/im/vector/app/features/ui/UiStateRepository.kt index e2a87ce226..b610346433 100644 --- a/vector/src/main/java/im/vector/app/features/ui/UiStateRepository.kt +++ b/vector/src/main/java/im/vector/app/features/ui/UiStateRepository.kt @@ -34,13 +34,7 @@ interface UiStateRepository { // TODO Handle SharedPreference per session in a better way, also to cleanup when login out fun storeSelectedSpace(spaceId: String?, sessionId: String) - fun storeSelectedGroup(groupId: String?, sessionId: String) - - fun storeGroupingMethod(isSpace: Boolean, sessionId: String) - fun getSelectedSpace(sessionId: String): String? - fun getSelectedGroup(sessionId: String): String? - fun isGroupingMethodSpace(sessionId: String): Boolean fun setCustomRoomDirectoryHomeservers(sessionId: String, servers: Set) fun getCustomRoomDirectoryHomeservers(sessionId: String): Set diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt index ff2d551212..8c377cafd5 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt @@ -29,7 +29,6 @@ import im.vector.app.features.createdirect.DirectRoomHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getUser import org.matrix.android.sdk.api.session.permalinks.PermalinkData @@ -42,7 +41,6 @@ class UserCodeSharedViewModel @AssistedInject constructor( private val session: Session, private val stringProvider: StringProvider, private val directRoomHelper: DirectRoomHelper, - private val rawService: RawService ) : VectorViewModel(initialState) { companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() @@ -129,15 +127,11 @@ class UserCodeSharedViewModel @AssistedInject constructor( ) } } - is PermalinkData.GroupLink -> { - // not yet supported - _viewEvents.post(UserCodeShareViewEvents.ToastMessage(stringProvider.getString(R.string.not_implemented))) - } + is PermalinkData.RoomEmailInviteLink, is PermalinkData.FallbackLink -> { // not yet supported _viewEvents.post(UserCodeShareViewEvents.ToastMessage(stringProvider.getString(R.string.not_implemented))) } - is PermalinkData.RoomEmailInviteLink -> Unit } _viewEvents.post(UserCodeShareViewEvents.HideWaitingScreen) } diff --git a/vector/src/main/res/layout/item_group.xml b/vector/src/main/res/layout/item_group.xml deleted file mode 100644 index 81fa43d072..0000000000 --- a/vector/src/main/res/layout/item_group.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 3b094ed7c2..eed6269e65 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -174,7 +174,8 @@ Initial sync:\nLoading your conversations\nIf you\'ve joined lots of rooms, this might take a while Initial sync:\nImporting invited rooms Initial sync:\nImporting left rooms - Initial sync:\nImporting communities + + Initial sync:\nImporting communities Initial sync:\nImporting account data Initial sync request @@ -442,7 +443,8 @@ Show all rooms in the room directory, including rooms with explicit content. - Communities + + Communities Spaces @@ -1614,7 +1616,8 @@ No network. Please check your Internet connection. "Change network" "Please wait…" - "All Communities" + + "All Communities" "This room can't be previewed" This room is not accessible at this time.\nTry again later, or ask a room admin to check if you have access. @@ -2084,6 +2087,7 @@ The current session is for user %1$s and you provide credentials for user %2$s. This is not supported by ${app_name}.\nPlease first clear data, then sign in again on another account. Your matrix.to link was malformed + Cannot open this link: communities have been replaced by spaces The description is too short Initial Sync…