mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-26 19:36:08 +03:00
Basic space join / use tmp msc id / db model update
This commit is contained in:
parent
ab4f2429c4
commit
e2578a29ed
28 changed files with 549 additions and 53 deletions
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.room.model
|
||||||
|
|
||||||
|
data class SpaceChildInfo(
|
||||||
|
val roomSummary: IRoomSummary?,
|
||||||
|
val present: Boolean,
|
||||||
|
val order: String?,
|
||||||
|
val autoJoin: Boolean,
|
||||||
|
val viaServers: List<String>
|
||||||
|
)
|
|
@ -21,7 +21,6 @@ import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
|
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
|
||||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
|
|
||||||
// TODO Give a way to include other initial states
|
// TODO Give a way to include other initial states
|
||||||
|
@ -112,7 +111,7 @@ open class CreateRoomParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var roomType: String? = RoomType.MESSAGING
|
var roomType: String? = null // RoomType.MESSAGING
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
|
|
@ -18,9 +18,10 @@ package org.matrix.android.sdk.api.session.space
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.IRoomSummary
|
import org.matrix.android.sdk.api.session.room.model.IRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
|
||||||
|
|
||||||
data class SpaceSummary(
|
data class SpaceSummary(
|
||||||
val spaceId: String,
|
val spaceId: String,
|
||||||
val roomSummary: RoomSummary,
|
val roomSummary: RoomSummary,
|
||||||
val children: List<IRoomSummary>
|
val children: List<SpaceChildInfo>
|
||||||
) : IRoomSummary by roomSummary
|
) : IRoomSummary by roomSummary
|
||||||
|
|
|
@ -49,5 +49,5 @@ data class SpaceChildContent(
|
||||||
* The default flag on a child listing allows a space admin to list the "default" sub-spaces and rooms in that space.
|
* The default flag on a child listing allows a space admin to list the "default" sub-spaces and rooms in that space.
|
||||||
* This means that when a user joins the parent space, they will automatically be joined to those default children.
|
* This means that when a user joins the parent space, they will automatically be joined to those default children.
|
||||||
*/
|
*/
|
||||||
@Json(name = "default") val default: Boolean? = true
|
@Json(name = "default") val default: Boolean? = false
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import kotlinx.coroutines.CompletableDeferred
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
internal suspend fun <T> awaitNotEmptyResult(realmConfiguration: RealmConfiguration,
|
internal suspend fun <T> awaitNotEmptyResult(realmConfiguration: RealmConfiguration,
|
||||||
timeoutMillis: Long,
|
timeoutMillis: Long,
|
||||||
|
@ -40,6 +41,7 @@ internal suspend fun <T> awaitNotEmptyResult(realmConfiguration: RealmConfigurat
|
||||||
|
|
||||||
val listener = object : RealmChangeListener<RealmResults<T>> {
|
val listener = object : RealmChangeListener<RealmResults<T>> {
|
||||||
override fun onChange(it: RealmResults<T>) {
|
override fun onChange(it: RealmResults<T>) {
|
||||||
|
Timber.v("## Space: $it")
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
result.removeChangeListener(this)
|
result.removeChangeListener(this)
|
||||||
latch.complete(Unit)
|
latch.complete(Unit)
|
||||||
|
|
|
@ -29,9 +29,9 @@ import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityField
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
|
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
|
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.database.model.SpaceChildInfoEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntityFields
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -207,9 +207,16 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
|
||||||
obj.setString(RoomSummaryEntityFields.ROOM_TYPE, null)
|
obj.setString(RoomSummaryEntityFields.ROOM_TYPE, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val spaceChildInfoSchema = realm.schema.create("SpaceChildInfoEntity")
|
||||||
|
?.addField(SpaceChildInfoEntityFields.ORDER, String::class.java)
|
||||||
|
?.addField(SpaceChildInfoEntityFields.PRESENT, Boolean::class.java)
|
||||||
|
?.setNullable(SpaceChildInfoEntityFields.PRESENT, true)
|
||||||
|
?.addRealmListField(SpaceChildInfoEntityFields.VIA_SERVERS.`$`, String::class.java)
|
||||||
|
?.addRealmObjectField(SpaceChildInfoEntityFields.ROOM_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!)
|
||||||
|
|
||||||
realm.schema.create("SpaceSummaryEntity")
|
realm.schema.create("SpaceSummaryEntity")
|
||||||
?.addField(SpaceSummaryEntityFields.SPACE_ID, String::class.java, FieldAttribute.PRIMARY_KEY)
|
?.addField(SpaceSummaryEntityFields.SPACE_ID, String::class.java, FieldAttribute.PRIMARY_KEY)
|
||||||
?.addRealmObjectField(SpaceSummaryEntityFields.ROOM_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!)
|
?.addRealmObjectField(SpaceSummaryEntityFields.ROOM_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!)
|
||||||
?.addRealmListField(SpaceSummaryEntityFields.CHILDREN.`$`, realm.schema.get("RoomSummaryEntity")!!)
|
?.addRealmListField(SpaceSummaryEntityFields.CHILDREN.`$`, spaceChildInfoSchema!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.database.mapper
|
package org.matrix.android.sdk.internal.database.mapper
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
||||||
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -27,7 +28,13 @@ internal class SpaceSummaryMapper @Inject constructor(private val roomSummaryMap
|
||||||
spaceId = spaceSummaryEntity.spaceId,
|
spaceId = spaceSummaryEntity.spaceId,
|
||||||
roomSummary = roomSummaryMapper.map(spaceSummaryEntity.roomSummaryEntity!!),
|
roomSummary = roomSummaryMapper.map(spaceSummaryEntity.roomSummaryEntity!!),
|
||||||
children = spaceSummaryEntity.children.map {
|
children = spaceSummaryEntity.children.map {
|
||||||
roomSummaryMapper.map(it)
|
SpaceChildInfo(
|
||||||
|
roomSummary = it.roomSummaryEntity?.let { rs -> roomSummaryMapper.map(rs) },
|
||||||
|
autoJoin = it.autoJoin ?: false,
|
||||||
|
present = it.present ?: false,
|
||||||
|
viaServers = it.viaServers.map { it },
|
||||||
|
order = it.order
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ import io.realm.annotations.RealmModule
|
||||||
UserAccountDataEntity::class,
|
UserAccountDataEntity::class,
|
||||||
ScalarTokenEntity::class,
|
ScalarTokenEntity::class,
|
||||||
WellknownIntegrationManagerConfigEntity::class,
|
WellknownIntegrationManagerConfigEntity::class,
|
||||||
SpaceSummaryEntity::class
|
SpaceSummaryEntity::class,
|
||||||
|
SpaceChildInfoEntity::class
|
||||||
])
|
])
|
||||||
internal class SessionRealmModule
|
internal class SessionRealmModule
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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 org.matrix.android.sdk.internal.database.model
|
||||||
|
|
||||||
|
import io.realm.RealmList
|
||||||
|
import io.realm.RealmObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorates room summary with space related information.
|
||||||
|
*/
|
||||||
|
internal open class SpaceChildInfoEntity(
|
||||||
|
var viaServers: RealmList<String> = RealmList(),
|
||||||
|
// it's an active child of the space if and only if present is not null and true
|
||||||
|
var present: Boolean? = null,
|
||||||
|
// Use for alphabetic ordering of this child
|
||||||
|
var order: String? = null,
|
||||||
|
// If true, this child should be join when parent is joined
|
||||||
|
var autoJoin: Boolean? = null,
|
||||||
|
// link to the actual room (check type to see if it's a subspace)
|
||||||
|
var roomSummaryEntity: RoomSummaryEntity? = null
|
||||||
|
) : RealmObject() {
|
||||||
|
|
||||||
|
companion object
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
internal open class SpaceSummaryEntity(@PrimaryKey var spaceId: String = "",
|
internal open class SpaceSummaryEntity(@PrimaryKey var spaceId: String = "",
|
||||||
var roomSummaryEntity: RoomSummaryEntity? = null,
|
var roomSummaryEntity: RoomSummaryEntity? = null,
|
||||||
var children: RealmList<RoomSummaryEntity> = RealmList()
|
var children: RealmList<SpaceChildInfoEntity> = RealmList()
|
||||||
// TODO public / private .. and more
|
// TODO public / private .. and more
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,9 @@ import org.matrix.android.sdk.internal.session.room.typing.DefaultSendTypingTask
|
||||||
import org.matrix.android.sdk.internal.session.room.typing.SendTypingTask
|
import org.matrix.android.sdk.internal.session.room.typing.SendTypingTask
|
||||||
import org.matrix.android.sdk.internal.session.room.uploads.DefaultGetUploadsTask
|
import org.matrix.android.sdk.internal.session.room.uploads.DefaultGetUploadsTask
|
||||||
import org.matrix.android.sdk.internal.session.room.uploads.GetUploadsTask
|
import org.matrix.android.sdk.internal.session.room.uploads.GetUploadsTask
|
||||||
|
import org.matrix.android.sdk.internal.session.space.DefaultJoinSpaceTask
|
||||||
import org.matrix.android.sdk.internal.session.space.DefaultSpaceService
|
import org.matrix.android.sdk.internal.session.space.DefaultSpaceService
|
||||||
|
import org.matrix.android.sdk.internal.session.space.JoinSpaceTask
|
||||||
import org.matrix.android.sdk.internal.session.space.peeking.DefaultPeekSpaceTask
|
import org.matrix.android.sdk.internal.session.space.peeking.DefaultPeekSpaceTask
|
||||||
import org.matrix.android.sdk.internal.session.space.peeking.PeekSpaceTask
|
import org.matrix.android.sdk.internal.session.space.peeking.PeekSpaceTask
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
|
@ -241,6 +243,9 @@ internal abstract class RoomModule {
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindPeekSpaceTask(task: DefaultPeekSpaceTask): PeekSpaceTask
|
abstract fun bindPeekSpaceTask(task: DefaultPeekSpaceTask): PeekSpaceTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindJoinSpaceTask(task: DefaultJoinSpaceTask): JoinSpaceTask
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindGetEventTask(task: DefaultGetEventTask): GetEventTask
|
abstract fun bindGetEventTask(task: DefaultGetEventTask): GetEventTask
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.query.whereType
|
import org.matrix.android.sdk.internal.database.query.whereType
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relationship between rooms and spaces
|
* Relationship between rooms and spaces
|
||||||
|
@ -38,13 +39,30 @@ internal class RoomRelationshipHelper(private val realm: Realm,
|
||||||
private val roomId: String
|
private val roomId: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getDirectChildrenDescriptions(): List<String> {
|
data class SpaceChildInfo(
|
||||||
|
val roomId: String,
|
||||||
|
val present: Boolean,
|
||||||
|
val order: String?,
|
||||||
|
val autoJoin: Boolean,
|
||||||
|
val viaServers: List<String>
|
||||||
|
)
|
||||||
|
|
||||||
|
fun getDirectChildrenDescriptions(): List<SpaceChildInfo> {
|
||||||
return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_CHILD)
|
return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_CHILD)
|
||||||
.findAll()
|
.findAll()
|
||||||
.filter { ContentMapper.map(it.root?.content).toModel<SpaceChildContent>()?.present == true }
|
// .filter { ContentMapper.map(it.root?.content).toModel<SpaceChildContent>()?.present == true }
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
// ContentMapper.map(it.root?.content).toModel<SpaceChildContent>()
|
// ContentMapper.map(it.root?.content).toModel<SpaceChildContent>()
|
||||||
it.stateKey
|
ContentMapper.map(it.root?.content).toModel<SpaceChildContent>()?.let { scc ->
|
||||||
|
Timber.d("## Space child desc state event $scc")
|
||||||
|
SpaceChildInfo(
|
||||||
|
roomId = it.stateKey,
|
||||||
|
present = scc.present ?: false,
|
||||||
|
order = scc.order,
|
||||||
|
autoJoin = scc.default ?: false,
|
||||||
|
viaServers = scc.via ?: emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.internal.session.room.summary
|
package org.matrix.android.sdk.internal.session.room.summary
|
||||||
|
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
|
import io.realm.kotlin.createObject
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
@ -38,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
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.RoomSummaryEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.SpaceChildInfoEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendStates
|
import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendStates
|
||||||
|
@ -162,13 +164,26 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomType == RoomType.SPACE) {
|
if (roomType == RoomType.SPACE) {
|
||||||
val spaceSummaryEntity = SpaceSummaryEntity.getOrCreate(realm, roomId)
|
Timber.v("## Space: Updating summary for Space $roomId membership: ${roomSummaryEntity.membership}")
|
||||||
|
val spaceSummaryEntity = SpaceSummaryEntity()
|
||||||
|
spaceSummaryEntity.spaceId = roomId
|
||||||
spaceSummaryEntity.roomSummaryEntity = roomSummaryEntity
|
spaceSummaryEntity.roomSummaryEntity = roomSummaryEntity
|
||||||
spaceSummaryEntity.children.clear()
|
spaceSummaryEntity.children.clear()
|
||||||
spaceSummaryEntity.children.addAll(
|
spaceSummaryEntity.children.addAll(
|
||||||
RoomRelationshipHelper(realm, roomId).getDirectChildrenDescriptions()
|
RoomRelationshipHelper(realm, roomId).getDirectChildrenDescriptions()
|
||||||
.map { RoomSummaryEntity.getOrCreate(realm, it) }
|
.map {
|
||||||
|
Timber.v("## Space: Updating summary for room $roomId with info $it")
|
||||||
|
realm.createObject<SpaceChildInfoEntity>().apply {
|
||||||
|
this.roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, it.roomId)
|
||||||
|
this.order = it.order
|
||||||
|
this.present = it.present
|
||||||
|
this.autoJoin = it.autoJoin
|
||||||
|
}.also {
|
||||||
|
Timber.v("## Space: Updating summary for room $roomId with children $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
realm.insertOrUpdate(spaceSummaryEntity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ internal class DefaultSpaceService @Inject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val createRoomTask: CreateRoomTask,
|
private val createRoomTask: CreateRoomTask,
|
||||||
private val joinRoomTask: JoinRoomTask,
|
private val joinRoomTask: JoinRoomTask,
|
||||||
|
private val joinSpaceTask: JoinSpaceTask,
|
||||||
private val markAllRoomsReadTask: MarkAllRoomsReadTask,
|
private val markAllRoomsReadTask: MarkAllRoomsReadTask,
|
||||||
private val updateBreadcrumbsTask: UpdateBreadcrumbsTask,
|
private val updateBreadcrumbsTask: UpdateBreadcrumbsTask,
|
||||||
private val roomIdByAliasTask: GetRoomIdByAliasTask,
|
private val roomIdByAliasTask: GetRoomIdByAliasTask,
|
||||||
|
@ -77,22 +78,24 @@ internal class DefaultSpaceService @Inject constructor(
|
||||||
|
|
||||||
override suspend fun joinSpace(spaceIdOrAlias: String, reason: String?, viaServers: List<String>, autoJoinChild: List<SpaceService.ChildAutoJoinInfo>): SpaceService.JoinSpaceResult {
|
override suspend fun joinSpace(spaceIdOrAlias: String, reason: String?, viaServers: List<String>, autoJoinChild: List<SpaceService.ChildAutoJoinInfo>): SpaceService.JoinSpaceResult {
|
||||||
try {
|
try {
|
||||||
joinRoomTask.execute(JoinRoomTask.Params(spaceIdOrAlias, reason, viaServers))
|
joinSpaceTask.execute(JoinSpaceTask.Params(spaceIdOrAlias, reason, viaServers))
|
||||||
val childJoinFailures = mutableMapOf<String, Throwable>()
|
// TODO partial success
|
||||||
autoJoinChild.forEach { info ->
|
return SpaceService.JoinSpaceResult.Success
|
||||||
// TODO what if the child is it self a subspace with some default children?
|
// val childJoinFailures = mutableMapOf<String, Throwable>()
|
||||||
try {
|
// autoJoinChild.forEach { info ->
|
||||||
joinRoomTask.execute(JoinRoomTask.Params(info.roomIdOrAlias, null, info.viaServers))
|
// // TODO what if the child is it self a subspace with some default children?
|
||||||
} catch (failure: Throwable) {
|
// try {
|
||||||
// TODO, i could already be a member of this room, handle that as it should not be an error in this context
|
// joinRoomTask.execute(JoinRoomTask.Params(info.roomIdOrAlias, null, info.viaServers))
|
||||||
childJoinFailures[info.roomIdOrAlias] = failure
|
// } catch (failure: Throwable) {
|
||||||
}
|
// // TODO, i could already be a member of this room, handle that as it should not be an error in this context
|
||||||
}
|
// childJoinFailures[info.roomIdOrAlias] = failure
|
||||||
return if (childJoinFailures.isEmpty()) {
|
// }
|
||||||
SpaceService.JoinSpaceResult.Success
|
// }
|
||||||
} else {
|
// return if (childJoinFailures.isEmpty()) {
|
||||||
SpaceService.JoinSpaceResult.PartialSuccess(childJoinFailures)
|
// SpaceService.JoinSpaceResult.Success
|
||||||
}
|
// } else {
|
||||||
|
// SpaceService.JoinSpaceResult.PartialSuccess(childJoinFailures)
|
||||||
|
// }
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
return SpaceService.JoinSpaceResult.Fail(throwable)
|
return SpaceService.JoinSpaceResult.Fail(throwable)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* 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 org.matrix.android.sdk.internal.session.space
|
||||||
|
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||||
|
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
||||||
|
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.SpaceSummaryEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||||
|
import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomTask
|
||||||
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal interface JoinSpaceTask : Task<JoinSpaceTask.Params, Unit> {
|
||||||
|
data class Params(
|
||||||
|
val roomIdOrAlias: String,
|
||||||
|
val reason: String?,
|
||||||
|
val viaServers: List<String> = emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultJoinSpaceTask @Inject constructor(
|
||||||
|
private val roomAPI: RoomAPI,
|
||||||
|
private val joinRoomTask: JoinRoomTask,
|
||||||
|
@SessionDatabase
|
||||||
|
private val realmConfiguration: RealmConfiguration,
|
||||||
|
private val spaceSummaryDataSource: SpaceSummaryDataSource,
|
||||||
|
private val eventBus: EventBus
|
||||||
|
) : JoinSpaceTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: JoinSpaceTask.Params) {
|
||||||
|
Timber.v("## Space: > Joining root space ${params.roomIdOrAlias} ...")
|
||||||
|
joinRoomTask.execute(JoinRoomTask.Params(
|
||||||
|
params.roomIdOrAlias,
|
||||||
|
params.reason,
|
||||||
|
params.viaServers
|
||||||
|
))
|
||||||
|
Timber.v("## Space: < Joining root space done for ${params.roomIdOrAlias}")
|
||||||
|
// we want to wait for sync result to check for auto join rooms
|
||||||
|
|
||||||
|
Timber.v("## Space: > Wait for post joined sync ${params.roomIdOrAlias} ...")
|
||||||
|
try {
|
||||||
|
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(2L)) { realm ->
|
||||||
|
realm.where(SpaceSummaryEntity::class.java)
|
||||||
|
.apply {
|
||||||
|
if (params.roomIdOrAlias.startsWith("!")) {
|
||||||
|
equalTo(SpaceSummaryEntityFields.SPACE_ID, params.roomIdOrAlias)
|
||||||
|
} else {
|
||||||
|
equalTo(SpaceSummaryEntityFields.ROOM_SUMMARY_ENTITY.CANONICAL_ALIAS, params.roomIdOrAlias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.equalTo(SpaceSummaryEntityFields.ROOM_SUMMARY_ENTITY.MEMBERSHIP_STR, Membership.JOIN.name)
|
||||||
|
}
|
||||||
|
} catch (exception: TimeoutCancellationException) {
|
||||||
|
Timber.w("## Space: > Error created with timeout")
|
||||||
|
throw CreateRoomFailure.CreatedWithTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
Timber.v("## Space: > Sync done ...")
|
||||||
|
// after that i should have the children (? do i nead to paginate to get state)
|
||||||
|
val summary = spaceSummaryDataSource.getSpaceSummary(params.roomIdOrAlias)
|
||||||
|
Timber.v("## Space: Found space summary Name:[${summary?.roomSummary?.name}] children: ${summary?.children?.size}")
|
||||||
|
summary?.children?.forEach {
|
||||||
|
val childRoomSummary = it.roomSummary ?: return@forEach
|
||||||
|
Timber.v("## Space: Processing child :[${childRoomSummary.roomId}] present: ${it.present} autoJoin:${it.autoJoin}")
|
||||||
|
if (it.present && it.autoJoin) {
|
||||||
|
// I should try to join as well
|
||||||
|
if (childRoomSummary.roomType == RoomType.SPACE) {
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Timber.v("## Space: Joining room child ${childRoomSummary.roomId}")
|
||||||
|
joinRoomTask.execute(JoinRoomTask.Params(
|
||||||
|
roomIdOrAlias = childRoomSummary.roomId,
|
||||||
|
reason = "Auto-join parent space",
|
||||||
|
viaServers = it.viaServers
|
||||||
|
))
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
// todo keep track for partial success
|
||||||
|
Timber.e("## Space: Failed to join room child ${childRoomSummary.roomId}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||||
|
// realm.where(RoomEntity::class.java)
|
||||||
|
// .equalTo(RoomEntityFields.ROOM_ID, roomId)
|
||||||
|
// }
|
||||||
|
// } catch (exception: TimeoutCancellationException) {
|
||||||
|
// throw CreateRoomFailure.CreatedWithTimeout
|
||||||
|
// }
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 New Vector Ltd
|
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -212,6 +212,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||||
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
|
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
|
||||||
val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, insertType)
|
val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, insertType)
|
||||||
CurrentStateEventEntity.getOrCreate(realm, roomId, event.stateKey, event.type).apply {
|
CurrentStateEventEntity.getOrCreate(realm, roomId, event.stateKey, event.type).apply {
|
||||||
|
Timber.v("## Space state event: $eventEntity")
|
||||||
eventId = event.eventId
|
eventId = event.eventId
|
||||||
root = eventEntity
|
root = eventEntity
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,7 @@
|
||||||
|
|
||||||
<activity android:name=".features.devtools.RoomDevToolActivity"/>
|
<activity android:name=".features.devtools.RoomDevToolActivity"/>
|
||||||
<activity android:name=".features.spaces.SpacePreviewActivity"/>
|
<activity android:name=".features.spaces.SpacePreviewActivity"/>
|
||||||
|
<activity android:name=".features.spaces.SpaceExploreActivity"/>
|
||||||
<!-- Services -->
|
<!-- Services -->
|
||||||
|
|
||||||
<service
|
<service
|
||||||
|
|
|
@ -52,7 +52,6 @@ import im.vector.app.features.devtools.RoomDevToolStateEventListFragment
|
||||||
import im.vector.app.features.discovery.DiscoverySettingsFragment
|
import im.vector.app.features.discovery.DiscoverySettingsFragment
|
||||||
import im.vector.app.features.discovery.change.SetIdentityServerFragment
|
import im.vector.app.features.discovery.change.SetIdentityServerFragment
|
||||||
import im.vector.app.features.grouplist.GroupListFragment
|
import im.vector.app.features.grouplist.GroupListFragment
|
||||||
import im.vector.app.features.grouplist.SpaceListFragment
|
|
||||||
import im.vector.app.features.home.HomeDetailFragment
|
import im.vector.app.features.home.HomeDetailFragment
|
||||||
import im.vector.app.features.home.HomeDrawerFragment
|
import im.vector.app.features.home.HomeDrawerFragment
|
||||||
import im.vector.app.features.home.LoadingFragment
|
import im.vector.app.features.home.LoadingFragment
|
||||||
|
@ -118,6 +117,7 @@ import im.vector.app.features.settings.push.PushRulesFragment
|
||||||
import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment
|
import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment
|
||||||
import im.vector.app.features.share.IncomingShareFragment
|
import im.vector.app.features.share.IncomingShareFragment
|
||||||
import im.vector.app.features.signout.soft.SoftLogoutFragment
|
import im.vector.app.features.signout.soft.SoftLogoutFragment
|
||||||
|
import im.vector.app.features.spaces.SpaceListFragment
|
||||||
import im.vector.app.features.spaces.preview.SpacePreviewFragment
|
import im.vector.app.features.spaces.preview.SpacePreviewFragment
|
||||||
import im.vector.app.features.terms.ReviewTermsFragment
|
import im.vector.app.features.terms.ReviewTermsFragment
|
||||||
import im.vector.app.features.usercode.ShowUserCodeFragment
|
import im.vector.app.features.usercode.ShowUserCodeFragment
|
||||||
|
|
|
@ -31,9 +31,9 @@ import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||||
import im.vector.app.databinding.FragmentHomeDrawerBinding
|
import im.vector.app.databinding.FragmentHomeDrawerBinding
|
||||||
import im.vector.app.features.grouplist.GroupListFragment
|
import im.vector.app.features.grouplist.GroupListFragment
|
||||||
import im.vector.app.features.grouplist.SpaceListFragment
|
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.settings.VectorSettingsActivity
|
import im.vector.app.features.settings.VectorSettingsActivity
|
||||||
|
import im.vector.app.features.spaces.SpaceListFragment
|
||||||
import im.vector.app.features.usercode.UserCodeActivity
|
import im.vector.app.features.usercode.UserCodeActivity
|
||||||
import im.vector.app.features.workers.signout.SignOutUiWorker
|
import im.vector.app.features.workers.signout.SignOutUiWorker
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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.spaces
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.airbnb.mvrx.MvRx
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.extensions.commitTransaction
|
||||||
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
|
import im.vector.app.databinding.ActivitySimpleBinding
|
||||||
|
import im.vector.app.features.spaces.explore.SpaceDirectoryArgs
|
||||||
|
import im.vector.app.features.spaces.explore.SpaceDirectoryFragment
|
||||||
|
import im.vector.app.features.spaces.preview.SpacePreviewArgs
|
||||||
|
import im.vector.app.features.spaces.preview.SpacePreviewFragment
|
||||||
|
|
||||||
|
class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||||
|
|
||||||
|
override fun getBinding(): ActivitySimpleBinding = ActivitySimpleBinding.inflate(layoutInflater)
|
||||||
|
// lateinit var sharedActionViewModel: SpacePreviewSharedActionViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
// sharedActionViewModel = viewModelProvider.get(SpacePreviewSharedActionViewModel::class.java)
|
||||||
|
// sharedActionViewModel
|
||||||
|
// .observe()
|
||||||
|
// .subscribe { action ->
|
||||||
|
// when (action) {
|
||||||
|
// SpacePreviewSharedAction.DismissAction -> finish()
|
||||||
|
// SpacePreviewSharedAction.ShowModalLoading -> showWaitingView()
|
||||||
|
// SpacePreviewSharedAction.HideModalLoading -> hideWaitingView()
|
||||||
|
// is SpacePreviewSharedAction.ShowErrorMessage -> action.error?.let { showSnackbar(it) }
|
||||||
|
// }
|
||||||
|
// }.disposeOnDestroy()
|
||||||
|
|
||||||
|
if (isFirstCreation()) {
|
||||||
|
val simpleName = SpaceDirectoryFragment::class.java.simpleName
|
||||||
|
val args = intent?.getParcelableExtra<SpacePreviewArgs>(MvRx.KEY_ARG)
|
||||||
|
if (supportFragmentManager.findFragmentByTag(simpleName) == null) {
|
||||||
|
supportFragmentManager.commitTransaction {
|
||||||
|
replace(R.id.simpleFragmentContainer,
|
||||||
|
SpacePreviewFragment::class.java,
|
||||||
|
Bundle().apply { this.putParcelable(MvRx.KEY_ARG, args) },
|
||||||
|
simpleName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newIntent(context: Context, spaceId: String): Intent {
|
||||||
|
return Intent(context, SpaceExploreActivity::class.java).apply {
|
||||||
|
putExtra(MvRx.KEY_ARG, SpaceDirectoryArgs(spaceId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,20 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright (c) 2021 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.grouplist
|
package im.vector.app.features.spaces
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -33,9 +32,6 @@ import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentGroupListBinding
|
import im.vector.app.databinding.FragmentGroupListBinding
|
||||||
import im.vector.app.features.home.HomeActivitySharedAction
|
import im.vector.app.features.home.HomeActivitySharedAction
|
||||||
import im.vector.app.features.home.HomeSharedActionViewModel
|
import im.vector.app.features.home.HomeSharedActionViewModel
|
||||||
import im.vector.app.features.spaces.SpaceListAction
|
|
||||||
import im.vector.app.features.spaces.SpaceListViewEvents
|
|
||||||
import im.vector.app.features.spaces.SpacesListViewModel
|
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright (c) 2021 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.grouplist
|
package im.vector.app.features.spaces
|
||||||
|
|
||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.ui.list.genericFooterItem
|
import im.vector.app.core.ui.list.genericFooterItem
|
||||||
import im.vector.app.core.ui.list.genericItemHeader
|
import im.vector.app.core.ui.list.genericItemHeader
|
||||||
|
import im.vector.app.features.grouplist.homeSpaceSummaryItem
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.spaces.SpaceListViewState
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
|
@ -87,7 +86,6 @@ class SpaceSummaryController @Inject constructor(
|
||||||
summaries
|
summaries
|
||||||
.filter { it.roomSummary.membership == Membership.JOIN }
|
.filter { it.roomSummary.membership == Membership.JOIN }
|
||||||
.forEach { groupSummary ->
|
.forEach { groupSummary ->
|
||||||
|
|
||||||
val isSelected = groupSummary.spaceId == selected?.spaceId
|
val isSelected = groupSummary.spaceId == selected?.spaceId
|
||||||
if (groupSummary.spaceId == ALL_COMMUNITIES_GROUP_ID) {
|
if (groupSummary.spaceId == ALL_COMMUNITIES_GROUP_ID) {
|
||||||
homeSpaceSummaryItem {
|
homeSpaceSummaryItem {
|
|
@ -15,7 +15,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.grouplist
|
package im.vector.app.features.spaces
|
||||||
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
|
@ -31,14 +31,12 @@ import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.grouplist.SelectedSpaceDataSource
|
import im.vector.app.features.grouplist.SelectedSpaceDataSource
|
||||||
import im.vector.app.features.grouplist.SpaceListFragment
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
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.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
||||||
import org.matrix.android.sdk.rx.rx
|
import org.matrix.android.sdk.rx.rx
|
||||||
|
@ -117,9 +115,11 @@ class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: Sp
|
||||||
// PRIVATE METHODS *****************************************************************************
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
|
||||||
private fun handleSelectSpace(action: SpaceListAction.SelectSpace) = withState { state ->
|
private fun handleSelectSpace(action: SpaceListAction.SelectSpace) = withState { state ->
|
||||||
|
// get uptodate version of the space
|
||||||
if (state.selectedSpace?.roomSummary?.membership == Membership.INVITE) {
|
val summary = session.spaceService().getSpaceSummaries(roomSummaryQueryParams { roomId = QueryStringValue.Equals(action.spaceSummary.spaceId) })
|
||||||
_viewEvents.post(SpaceListViewEvents.OpenSpaceSummary(state.selectedSpace.roomSummary.roomId))
|
.firstOrNull()
|
||||||
|
if (summary?.roomSummary?.membership == Membership.INVITE) {
|
||||||
|
_viewEvents.post(SpaceListViewEvents.OpenSpaceSummary(summary.roomSummary.roomId))
|
||||||
// viewModelScope.launch(Dispatchers.IO) {
|
// viewModelScope.launch(Dispatchers.IO) {
|
||||||
// tryOrNull { session.spaceService().peekSpace(action.spaceSummary.spaceId) }.let {
|
// tryOrNull { session.spaceService().peekSpace(action.spaceSummary.spaceId) }.let {
|
||||||
// Timber.d("PEEK RESULT/ $it")
|
// Timber.d("PEEK RESULT/ $it")
|
||||||
|
@ -139,7 +139,8 @@ class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: Sp
|
||||||
val roomSummaryQueryParams = roomSummaryQueryParams() {
|
val roomSummaryQueryParams = roomSummaryQueryParams() {
|
||||||
memberships = listOf(Membership.JOIN, Membership.INVITE)
|
memberships = listOf(Membership.JOIN, Membership.INVITE)
|
||||||
displayName = QueryStringValue.IsNotEmpty
|
displayName = QueryStringValue.IsNotEmpty
|
||||||
excludeType = listOf(RoomType.MESSAGING, null)
|
excludeType = listOf(/**RoomType.MESSAGING,$*/
|
||||||
|
null)
|
||||||
}
|
}
|
||||||
Observable.combineLatest<SpaceSummary, List<SpaceSummary>, List<SpaceSummary>>(
|
Observable.combineLatest<SpaceSummary, List<SpaceSummary>, List<SpaceSummary>>(
|
||||||
session
|
session
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.spaces.explore
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Incomplete
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||||
|
import im.vector.app.core.epoxy.loadingItem
|
||||||
|
|
||||||
|
class SpaceDirectoryController : TypedEpoxyController<SpaceDirectoryState>() {
|
||||||
|
|
||||||
|
override fun buildModels(data: SpaceDirectoryState?) {
|
||||||
|
when (data?.summary) {
|
||||||
|
is Success -> {
|
||||||
|
// val directories = roomDirectoryListCreator.computeDirectories(asyncThirdPartyProtocol())
|
||||||
|
//
|
||||||
|
// directories.forEach {
|
||||||
|
// buildDirectory(it)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
is Incomplete -> {
|
||||||
|
loadingItem {
|
||||||
|
id("loading")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Fail -> {
|
||||||
|
errorWithRetryItem {
|
||||||
|
id("error")
|
||||||
|
// text(errorFormatter.toHumanReadable(asyncThirdPartyProtocol.error))
|
||||||
|
// listener { callback?.retry() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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.spaces.explore
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
|
import im.vector.app.databinding.FragmentRoomDirectoryPickerBinding
|
||||||
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class SpaceDirectoryArgs(
|
||||||
|
val spaceId: String
|
||||||
|
) : Parcelable
|
||||||
|
|
||||||
|
class SpaceDirectoryFragment : VectorBaseFragment<FragmentRoomDirectoryPickerBinding>() {
|
||||||
|
|
||||||
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
|
||||||
|
FragmentRoomDirectoryPickerBinding.inflate(layoutInflater, container, false)
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.spaces.explore
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.airbnb.mvrx.ActivityViewModelContext
|
||||||
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
|
import org.matrix.android.sdk.api.session.space.SpaceSummary
|
||||||
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
|
import org.matrix.android.sdk.rx.rx
|
||||||
|
import org.matrix.android.sdk.rx.unwrap
|
||||||
|
|
||||||
|
data class SpaceDirectoryState(
|
||||||
|
// The current filter
|
||||||
|
val spaceId: String,
|
||||||
|
val currentFilter: String = "",
|
||||||
|
val summary: Async<SpaceSummary> = Uninitialized,
|
||||||
|
// True if more result are available server side
|
||||||
|
val hasMore: Boolean = false,
|
||||||
|
// Set of joined roomId / spaces,
|
||||||
|
val joinedRoomsIds: Set<String> = emptySet()
|
||||||
|
) : MvRxState {
|
||||||
|
constructor(args: SpaceDirectoryArgs) : this(spaceId = args.spaceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class SpaceDirectoryViewAction : VectorViewModelAction
|
||||||
|
|
||||||
|
sealed class SpaceDirectoryViewEvents : VectorViewEvents
|
||||||
|
|
||||||
|
class SpaceDirectoryViewModel @AssistedInject constructor(
|
||||||
|
@Assisted initialState: SpaceDirectoryState,
|
||||||
|
private val session: Session
|
||||||
|
) : VectorViewModel<SpaceDirectoryState, VectorViewModelAction, SpaceDirectoryViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<SpaceDirectoryViewModel, SpaceDirectoryState> {
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: SpaceDirectoryState): SpaceDirectoryViewModel? {
|
||||||
|
val factory = when (viewModelContext) {
|
||||||
|
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
|
||||||
|
is ActivityViewModelContext -> viewModelContext.activity as? Factory
|
||||||
|
}
|
||||||
|
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val queryParams = roomSummaryQueryParams {
|
||||||
|
roomId = QueryStringValue.Equals(initialState.spaceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
session
|
||||||
|
.rx()
|
||||||
|
.liveSpaceSummaries(queryParams)
|
||||||
|
.observeOn(Schedulers.computation())
|
||||||
|
.map { sum -> Optional.from(sum.firstOrNull()) }
|
||||||
|
.unwrap()
|
||||||
|
.execute { async ->
|
||||||
|
copy(summary = async)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handle(action: VectorViewModelAction) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue