Ignore/Unignore userIds

This commit is contained in:
Benoit Marty 2019-11-05 12:40:25 +01:00
parent 2f7d1f9f01
commit fbae3d27c2
10 changed files with 215 additions and 7 deletions

View File

@ -54,6 +54,10 @@ class RxSession(private val session: Session) {
return session.liveUsers().asObservable()
}
fun liveIgnoredUserIds(): Observable<List<String>> {
return session.liveIgnoredUserIds().asObservable()
}
fun livePagedUsers(filter: String? = null): Observable<PagedList<User>> {
return session.livePagedUsers(filter).asObservable()
}

View File

@ -64,4 +64,19 @@ interface UserService {
* @return a Livedata of users
*/
fun livePagedUsers(filter: String? = null): LiveData<PagedList<User>>
/**
* Get list of ignored users id
*/
fun liveIgnoredUserIds(): LiveData<List<String>>
/**
* Ignore users
*/
fun ignoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable
/**
* Un-ignore some users
*/
fun unIgnoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable
}

View File

@ -0,0 +1,24 @@
/*
* 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.matrix.android.internal.database.model
import io.realm.RealmObject
internal open class IgnoredUserEntity(var userId: String = "") : RealmObject() {
companion object
}

View File

@ -35,6 +35,7 @@ import io.realm.annotations.RealmModule
RoomTagEntity::class,
SyncEntity::class,
UserEntity::class,
IgnoredUserEntity::class,
EventAnnotationsSummaryEntity::class,
ReactionAggregatedSummaryEntity::class,
EditAggregatedSummaryEntity::class,

View File

@ -26,12 +26,10 @@ import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.pushers.SavePushRulesTask
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
import im.vector.matrix.android.internal.session.sync.model.*
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
import im.vector.matrix.android.internal.session.sync.model.accountdata.*
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
@ -45,6 +43,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
private val directChatsHelper: DirectChatsHelper,
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val savePushRulesTask: SavePushRulesTask,
private val saveIgnoredUsersTask: SaveIgnoredUsersTask,
private val taskExecutor: TaskExecutor) {
suspend fun handle(accountData: UserAccountDataSync?, invites: Map<String, InvitedRoomSync>?) {
@ -52,10 +51,18 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
when (it) {
is UserAccountDataDirectMessages -> handleDirectChatRooms(it)
is UserAccountDataPushRules -> handlePushRules(it)
is UserAccountDataIgnoredUsers -> handleIgnoredUsers(it)
is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}")
else -> error("Missing code here!")
}
}
// TODO Store all account data, app can be interested of it
// accountData?.list?.forEach {
// it.toString()
// MoshiProvider.providesMoshi()
// }
monarchy.doWithRealm { realm ->
synchronizeWithServerIfNeeded(realm, invites)
}
@ -116,4 +123,9 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
updateUserAccountDataTask.configureWith(updateUserAccountParams).executeBy(taskExecutor)
}
}
private fun handleIgnoredUsers(userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) {
saveIgnoredUsersTask.configureWith(userAccountDataIgnoredUsers).executeBy(taskExecutor)
// TODO If not initial sync, we should execute a init sync
}
}

View File

@ -29,9 +29,12 @@ import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
import im.vector.matrix.android.internal.database.model.IgnoredUserEntityFields
import im.vector.matrix.android.internal.database.model.UserEntity
import im.vector.matrix.android.internal.database.model.UserEntityFields
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask
import im.vector.matrix.android.internal.session.user.model.SearchUserTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
@ -40,8 +43,8 @@ import javax.inject.Inject
internal class DefaultUserService @Inject constructor(private val monarchy: Monarchy,
private val searchUserTask: SearchUserTask,
private val updateIgnoredUserIdsTask: UpdateIgnoredUserIdsTask,
private val taskExecutor: TaskExecutor) : UserService {
private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory<UserEntity> by lazy {
monarchy.createDataSourceFactory { realm ->
realm.where(UserEntity::class.java)
@ -62,7 +65,7 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
override fun getUser(userId: String): User? {
val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() }
?: return null
?: return null
return userEntity.asDomain()
}
@ -117,4 +120,33 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona
}
.executeBy(taskExecutor)
}
override fun liveIgnoredUserIds(): LiveData<List<String>> {
return monarchy.findAllMappedWithChanges(
{ realm ->
realm.where(IgnoredUserEntity::class.java)
.isNotEmpty(IgnoredUserEntityFields.USER_ID)
.sort(IgnoredUserEntityFields.USER_ID)
},
{ it.userId }
)
}
override fun ignoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable {
val params = UpdateIgnoredUserIdsTask.Params(userIdsToIgnore = userIds.toList())
return updateIgnoredUserIdsTask
.configureWith(params) {
this.callback = callback
}
.executeBy(taskExecutor)
}
override fun unIgnoreUserIds(userIds: List<String>, callback: MatrixCallback<Unit>): Cancelable {
val params = UpdateIgnoredUserIdsTask.Params(userIdsToUnIgnore = userIds.toList())
return updateIgnoredUserIdsTask
.configureWith(params) {
this.callback = callback
}
.executeBy(taskExecutor)
}
}

View File

@ -21,6 +21,10 @@ import dagger.Module
import dagger.Provides
import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.user.accountdata.DefaultSaveIgnoredUsersTask
import im.vector.matrix.android.internal.session.user.accountdata.DefaultUpdateIgnoredUserIdsTask
import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask
import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask
import im.vector.matrix.android.internal.session.user.model.DefaultSearchUserTask
import im.vector.matrix.android.internal.session.user.model.SearchUserTask
import retrofit2.Retrofit
@ -43,4 +47,10 @@ internal abstract class UserModule {
@Binds
abstract fun bindSearchUserTask(searchUserTask: DefaultSearchUserTask): SearchUserTask
@Binds
abstract fun bindSaveIgnoredUsersTask(task: DefaultSaveIgnoredUsersTask): SaveIgnoredUsersTask
@Binds
abstract fun bindUpdateIgnoredUserIdsTask(task: DefaultUpdateIgnoredUserIdsTask): UpdateIgnoredUserIdsTask
}

View File

@ -0,0 +1,45 @@
/*
* 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.matrix.android.internal.session.user.accountdata
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction
import javax.inject.Inject
/**
* Save the ignored users list in DB
*/
internal interface SaveIgnoredUsersTask : Task<UserAccountDataIgnoredUsers, Unit> {
data class Params(val pa: GetPushRulesResponse)
}
internal class DefaultSaveIgnoredUsersTask @Inject constructor(private val monarchy: Monarchy) : SaveIgnoredUsersTask {
override suspend fun execute(params: UserAccountDataIgnoredUsers) {
monarchy.awaitTransaction { realm ->
// clear current ignored users
realm.where(IgnoredUserEntity::class.java)
.findAll()
.deleteAllFromRealm()
params.content.ignoredUsers.keys.forEach { realm.createObject(IgnoredUserEntity::class.java, it) }
}
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.matrix.android.internal.session.user.accountdata
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
import im.vector.matrix.android.internal.task.Task
import javax.inject.Inject
internal interface UpdateIgnoredUserIdsTask : Task<UpdateIgnoredUserIdsTask.Params, Unit> {
data class Params(
val userIdsToIgnore: List<String> = emptyList(),
val userIdsToUnIgnore: List<String> = emptyList()
)
}
internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(private val accountDataApi: AccountDataAPI,
private val monarchy: Monarchy,
@UserId private val userId: String) : UpdateIgnoredUserIdsTask {
override suspend fun execute(params: UpdateIgnoredUserIdsTask.Params) {
// Get current list
val ignoredUserIds = monarchy.fetchAllMappedSync(
{ realm -> realm.where(IgnoredUserEntity::class.java) },
{ it.userId }
)
val original = ignoredUserIds.toList()
ignoredUserIds -= params.userIdsToUnIgnore
ignoredUserIds += params.userIdsToIgnore
if (original == ignoredUserIds) {
// No change
return
}
val body = UserAccountDataIgnoredUsers.createWithUserIds(ignoredUserIds)
return executeRequest {
apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body)
}
}
}

View File

@ -29,6 +29,7 @@ internal interface UpdateUserAccountDataTask : Task<UpdateUserAccountDataTask.Pa
fun getData(): Any
}
// TODO Use [UserAccountDataDirectMessages] class?
data class DirectChatParams(override val type: String = UserAccountData.TYPE_DIRECT_MESSAGES,
private val directMessages: Map<String, List<String>>
) : Params {