Handle left group from sync
This commit is contained in:
parent
91cc78d2ad
commit
a993a30203
@ -15,6 +15,7 @@ Other changes:
|
||||
Bugfix:
|
||||
- Fix characters erased from the Search field when the result are coming (#545)
|
||||
- "No connection" banner was displayed by mistake
|
||||
- Leaving community (from another client) has no effect on RiotX (#497)
|
||||
|
||||
Translations:
|
||||
-
|
||||
|
@ -16,12 +16,15 @@
|
||||
|
||||
package im.vector.matrix.android.api.session.group.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
|
||||
/**
|
||||
* This class holds some data of a group.
|
||||
* It can be retrieved through [im.vector.matrix.android.api.session.group.GroupService]
|
||||
*/
|
||||
data class GroupSummary(
|
||||
val groupId: String,
|
||||
val membership: Membership,
|
||||
val displayName: String = "",
|
||||
val shortDescription: String = "",
|
||||
val avatarUrl: String = "",
|
||||
|
@ -25,6 +25,7 @@ internal object GroupSummaryMapper {
|
||||
fun map(roomSummaryEntity: GroupSummaryEntity): GroupSummary {
|
||||
return GroupSummary(
|
||||
roomSummaryEntity.groupId,
|
||||
roomSummaryEntity.membership,
|
||||
roomSummaryEntity.displayName,
|
||||
roomSummaryEntity.shortDescription,
|
||||
roomSummaryEntity.avatarUrl,
|
||||
|
@ -20,9 +20,13 @@ import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
internal open class GroupEntity(@PrimaryKey var groupId: String = ""
|
||||
|
||||
) : RealmObject() {
|
||||
/**
|
||||
* This class is used to store group info (groupId and membership) from the sync response.
|
||||
* Then [im.vector.matrix.android.internal.session.group.GroupSummaryUpdater] observes change and
|
||||
* makes requests 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
|
||||
|
@ -16,18 +16,28 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
internal open class GroupSummaryEntity(@PrimaryKey var groupId: String = "",
|
||||
var displayName: String = "",
|
||||
var shortDescription: String = "",
|
||||
var avatarUrl: String = "",
|
||||
var roomIds: RealmList<String> = RealmList(),
|
||||
var userIds: RealmList<String> = RealmList()
|
||||
var displayName: String = "",
|
||||
var shortDescription: String = "",
|
||||
var avatarUrl: String = "",
|
||||
var roomIds: RealmList<String> = RealmList(),
|
||||
var userIds: RealmList<String> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
var membership: Membership
|
||||
get() {
|
||||
return Membership.valueOf(membershipStr)
|
||||
}
|
||||
set(value) {
|
||||
membershipStr = value.name
|
||||
}
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -23,9 +23,9 @@ import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<GroupEntity> {
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, groupId: String): RealmQuery<GroupEntity> {
|
||||
return realm.where<GroupEntity>()
|
||||
.equalTo(GroupEntityFields.GROUP_ID, roomId)
|
||||
.equalTo(GroupEntityFields.GROUP_ID, groupId)
|
||||
}
|
||||
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<GroupEntity> {
|
||||
|
@ -30,3 +30,7 @@ internal fun GroupSummaryEntity.Companion.where(realm: Realm, groupId: String? =
|
||||
return query
|
||||
}
|
||||
|
||||
internal fun GroupSummaryEntity.Companion.where(realm: Realm, groupIds: List<String>): RealmQuery<GroupSummaryEntity> {
|
||||
return realm.where<GroupSummaryEntity>()
|
||||
.`in`(GroupSummaryEntityFields.GROUP_ID, groupIds.toTypedArray())
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package im.vector.matrix.android.internal.session.group
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
@ -64,8 +65,7 @@ internal class DefaultGetGroupDataTask @Inject constructor(
|
||||
groupSummaryEntity.avatarUrl = groupSummary.profile?.avatarUrl ?: ""
|
||||
val name = groupSummary.profile?.name
|
||||
groupSummaryEntity.displayName = if (name.isNullOrEmpty()) groupId else name
|
||||
groupSummaryEntity.shortDescription = groupSummary.profile?.shortDescription
|
||||
?: ""
|
||||
groupSummaryEntity.shortDescription = groupSummary.profile?.shortDescription ?: ""
|
||||
|
||||
val roomIds = groupRooms.rooms.map { it.roomId }
|
||||
groupSummaryEntity.roomIds.clear()
|
||||
@ -74,8 +74,12 @@ internal class DefaultGetGroupDataTask @Inject constructor(
|
||||
val userIds = groupUsers.users.map { it.userId }
|
||||
groupSummaryEntity.userIds.clear()
|
||||
groupSummaryEntity.userIds.addAll(userIds)
|
||||
|
||||
groupSummaryEntity.membership = when (groupSummary.user?.membership) {
|
||||
Membership.JOIN.value -> Membership.JOIN
|
||||
Membership.INVITE.value -> Membership.INVITE
|
||||
else -> Membership.LEAVE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -21,15 +21,15 @@ import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.WorkManager
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntity
|
||||
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -37,18 +37,29 @@ private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
|
||||
|
||||
internal class GroupSummaryUpdater @Inject constructor(private val context: Context,
|
||||
private val credentials: Credentials,
|
||||
@SessionDatabase realmConfiguration: RealmConfiguration)
|
||||
: RealmLiveEntityObserver<GroupEntity>(realmConfiguration) {
|
||||
private val monarchy: Monarchy)
|
||||
: RealmLiveEntityObserver<GroupEntity>(monarchy.realmConfiguration) {
|
||||
|
||||
override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
|
||||
override val query = Monarchy.Query { GroupEntity.where(it) }
|
||||
|
||||
override fun onChange(results: RealmResults<GroupEntity>, changeSet: OrderedCollectionChangeSet) {
|
||||
val newGroupIds = changeSet.insertions
|
||||
// `insertions` for new groups and `changes` to handle left groups
|
||||
val modifiedGroupEntity = (changeSet.insertions + changeSet.changes)
|
||||
.asSequence()
|
||||
.mapNotNull { results[it]?.groupId}
|
||||
.mapNotNull { results[it] }
|
||||
.toList()
|
||||
|
||||
val getGroupDataWorkerParams = GetGroupDataWorker.Params(credentials.userId, newGroupIds)
|
||||
fetchGroupsData(modifiedGroupEntity
|
||||
.filter { it.membership == Membership.JOIN || it.membership == Membership.INVITE }
|
||||
.map { it.groupId })
|
||||
|
||||
deleteGroups(modifiedGroupEntity
|
||||
.filter { it.membership == Membership.LEAVE }
|
||||
.map { it.groupId })
|
||||
}
|
||||
|
||||
private fun fetchGroupsData(groupIds: List<String>) {
|
||||
val getGroupDataWorkerParams = GetGroupDataWorker.Params(credentials.userId, groupIds)
|
||||
val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
|
||||
|
||||
val sendWork = matrixOneTimeWorkRequestBuilder<GetGroupDataWorker>()
|
||||
@ -61,4 +72,15 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
|
||||
.enqueue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the GroupSummaryEntity of left groups
|
||||
*/
|
||||
private fun deleteGroups(groupIds: List<String>) {
|
||||
monarchy
|
||||
.writeAsync { realm ->
|
||||
GroupSummaryEntity.where(realm, groupIds)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
}
|
||||
}
|
@ -64,12 +64,13 @@ internal class GroupSyncHandler @Inject constructor(private val monarchy: Monarc
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Note: [im.vector.matrix.android.internal.session.group.GroupSummaryUpdater] is observing changes */
|
||||
realm.insertOrUpdate(groups)
|
||||
}
|
||||
|
||||
private fun handleJoinedGroup(realm: Realm,
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = Membership.JOIN
|
||||
return groupEntity
|
||||
@ -77,21 +78,16 @@ internal class GroupSyncHandler @Inject constructor(private val monarchy: Monarc
|
||||
|
||||
private fun handleInvitedGroup(realm: Realm,
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = Membership.INVITE
|
||||
return groupEntity
|
||||
|
||||
}
|
||||
|
||||
// TODO : handle it
|
||||
private fun handleLeftGroup(realm: Realm,
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = Membership.LEAVE
|
||||
return groupEntity
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -26,6 +26,7 @@ import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
@ -93,20 +94,20 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro
|
||||
session
|
||||
.rx()
|
||||
.liveGroupSummaries()
|
||||
// Keep only joined groups. Group invitations will be managed later
|
||||
.map { it.filter { groupSummary -> groupSummary.membership == Membership.JOIN } }
|
||||
.map {
|
||||
val myUser = session.getUser(session.myUserId)
|
||||
val allCommunityGroup = GroupSummary(
|
||||
groupId = ALL_COMMUNITIES_GROUP_ID,
|
||||
membership = Membership.JOIN,
|
||||
displayName = stringProvider.getString(R.string.group_all_communities),
|
||||
avatarUrl = myUser?.avatarUrl ?: "")
|
||||
listOf(allCommunityGroup) + it
|
||||
}
|
||||
.execute { async ->
|
||||
// TODO Phase2 Handle the case where the selected group is deleted on another client
|
||||
val newSelectedGroup = selectedGroup ?: async()?.firstOrNull()
|
||||
copy(asyncGroups = async, selectedGroup = newSelectedGroup)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user