Handle breadcrumbs from account data

This commit is contained in:
Benoit Marty 2019-12-05 12:13:45 +01:00
parent fb8ba32fb4
commit cec08a20e5
11 changed files with 145 additions and 0 deletions

View File

@ -38,6 +38,10 @@ class RxSession(private val session: Session) {
return session.liveGroupSummaries().asObservable() return session.liveGroupSummaries().asObservable()
} }
fun liveBreadcrumbs(): Observable<List<RoomSummary>> {
return session.liveBreadcrumbs().asObservable()
}
fun liveSyncState(): Observable<SyncState> { fun liveSyncState(): Observable<SyncState> {
return session.syncState().asObservable() return session.syncState().asObservable()
} }

View File

@ -54,6 +54,12 @@ interface RoomService {
*/ */
fun liveRoomSummaries(): LiveData<List<RoomSummary>> fun liveRoomSummaries(): LiveData<List<RoomSummary>>
/**
* Get a live list of Breadcrumbs
* @return the [LiveData] of [RoomSummary]
*/
fun liveBreadcrumbs(): LiveData<List<RoomSummary>>
/** /**
* Mark all rooms as read * Mark all rooms as read
*/ */

View File

@ -0,0 +1,25 @@
/*
* 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.RealmList
import io.realm.RealmObject
internal open class BreadcrumbsEntity(var roomIds: RealmList<String> = RealmList()) : RealmObject() {
companion object
}

View File

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

View File

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory
import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages 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.UserAccountDataFallback
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
@ -34,6 +35,7 @@ object MoshiProvider {
.registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES) .registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES)
.registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST) .registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST)
.registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES) .registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES)
.registerSubtype(UserAccountDataBreadcrumbs::class.java, UserAccountData.TYPE_BREADCRUMBS)
) )
.add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java) .add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
.registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT) .registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)

View File

@ -26,6 +26,7 @@ import im.vector.matrix.android.api.session.room.model.VersioningState
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity
import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
@ -36,6 +37,7 @@ import im.vector.matrix.android.internal.session.room.read.MarkAllRoomsReadTask
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import io.realm.Realm import io.realm.Realm
import io.realm.RealmList
import javax.inject.Inject import javax.inject.Inject
internal class DefaultRoomService @Inject constructor(private val monarchy: Monarchy, internal class DefaultRoomService @Inject constructor(private val monarchy: Monarchy,
@ -75,6 +77,18 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona
) )
} }
override fun liveBreadcrumbs(): LiveData<List<RoomSummary>> {
return monarchy.findAllMappedWithChanges(
{ realm ->
// TODO Improve this query, it's not live when breadcrumbs changes
realm.where(RoomSummaryEntity::class.java)
.`in`(RoomSummaryEntityFields.ROOM_ID,
(realm.where(BreadcrumbsEntity::class.java).findFirst()?.roomIds ?: RealmList()).toTypedArray())
},
{ roomSummaryMapper.map(it) }
)
}
override fun joinRoom(roomId: String, viaServers: List<String>, callback: MatrixCallback<Unit>): Cancelable { override fun joinRoom(roomId: String, viaServers: List<String>, callback: MatrixCallback<Unit>): Cancelable {
return joinRoomTask return joinRoomTask
.configureWith(JoinRoomTask.Params(roomId, viaServers)) { .configureWith(JoinRoomTask.Params(roomId, viaServers)) {

View File

@ -29,6 +29,7 @@ import im.vector.matrix.android.internal.session.room.membership.RoomMembers
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync 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.sync.model.accountdata.*
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
import im.vector.matrix.android.internal.session.user.accountdata.SaveBreadcrumbsTask
import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask 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.session.user.accountdata.UpdateUserAccountDataTask
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
@ -44,6 +45,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val savePushRulesTask: SavePushRulesTask, private val savePushRulesTask: SavePushRulesTask,
private val saveIgnoredUsersTask: SaveIgnoredUsersTask, private val saveIgnoredUsersTask: SaveIgnoredUsersTask,
private val saveBreadcrumbsTask: SaveBreadcrumbsTask,
private val taskExecutor: TaskExecutor) { private val taskExecutor: TaskExecutor) {
suspend fun handle(accountData: UserAccountDataSync?, invites: Map<String, InvitedRoomSync>?) { suspend fun handle(accountData: UserAccountDataSync?, invites: Map<String, InvitedRoomSync>?) {
@ -52,6 +54,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
is UserAccountDataDirectMessages -> handleDirectChatRooms(it) is UserAccountDataDirectMessages -> handleDirectChatRooms(it)
is UserAccountDataPushRules -> handlePushRules(it) is UserAccountDataPushRules -> handlePushRules(it)
is UserAccountDataIgnoredUsers -> handleIgnoredUsers(it) is UserAccountDataIgnoredUsers -> handleIgnoredUsers(it)
is UserAccountDataBreadcrumbs -> handleBreadcrumbs(it)
is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}") is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}")
else -> error("Missing code here!") else -> error("Missing code here!")
} }
@ -130,4 +133,10 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
.executeBy(taskExecutor) .executeBy(taskExecutor)
// TODO If not initial sync, we should execute a init sync // TODO If not initial sync, we should execute a init sync
} }
private fun handleBreadcrumbs(userAccountDataBreadcrumbs: UserAccountDataBreadcrumbs) {
saveBreadcrumbsTask
.configureWith(SaveBreadcrumbsTask.Params(userAccountDataBreadcrumbs.content.roomIds))
.executeBy(taskExecutor)
}
} }

View File

@ -25,6 +25,7 @@ internal abstract class UserAccountData {
companion object { companion object {
const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list" const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list"
const val TYPE_DIRECT_MESSAGES = "m.direct" const val TYPE_DIRECT_MESSAGES = "m.direct"
const val TYPE_BREADCRUMBS = "im.vector.setting.breadcrumbs" // Was previously "im.vector.riot.breadcrumb_rooms"
const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls" const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls"
const val TYPE_WIDGETS = "m.widgets" const val TYPE_WIDGETS = "m.widgets"
const val TYPE_PUSH_RULES = "m.push_rules" const val TYPE_PUSH_RULES = "m.push_rules"

View File

@ -0,0 +1,34 @@
/*
* 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.sync.model.accountdata
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class UserAccountDataBreadcrumbs(
@Json(name = "type") override val type: String = TYPE_BREADCRUMBS,
@Json(name = "content") val content: BreadcrumbsContent
) : UserAccountData()
@JsonClass(generateAdapter = true)
internal data class BreadcrumbsContent(
@Json(name = "rooms") val roomIds: List<String> = emptyList(),
// We also have "recent_rooms", I do not know what to do with that list
@Json(name = "recent_rooms") val recentRoomIds: List<String> = emptyList()
)

View File

@ -36,4 +36,7 @@ internal abstract class AccountDataModule {
@Binds @Binds
abstract fun bindUpdateUserAccountDataTask(updateUserAccountDataTask: DefaultUpdateUserAccountDataTask): UpdateUserAccountDataTask abstract fun bindUpdateUserAccountDataTask(updateUserAccountDataTask: DefaultUpdateUserAccountDataTask): UpdateUserAccountDataTask
@Binds
abstract fun bindSaveBreadcrumbsTask(saveBreadcrumbsTask: DefaultSaveBreadcrumbsTask): SaveBreadcrumbsTask
} }

View File

@ -0,0 +1,46 @@
/*
* 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.BreadcrumbsEntity
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.awaitTransaction
import io.realm.RealmList
import javax.inject.Inject
/**
* Save the Breadcrumbs roomId list in DB
*/
internal interface SaveBreadcrumbsTask : Task<SaveBreadcrumbsTask.Params, Unit> {
data class Params(
val roomIds: List<String>
)
}
internal class DefaultSaveBreadcrumbsTask @Inject constructor(private val monarchy: Monarchy) : SaveBreadcrumbsTask {
override suspend fun execute(params: SaveBreadcrumbsTask.Params) {
monarchy.awaitTransaction { realm ->
// Get or create a breadcrumbs entity
val entity = realm.where(BreadcrumbsEntity::class.java).findFirst()
?: realm.createObject(BreadcrumbsEntity::class.java)
// And save the new received list
entity.roomIds = RealmList<String>().apply { addAll(params.roomIds) }
}
}
}