Introduce a very simple query langage and refact autocomplete
This commit is contained in:
parent
c60b4ddb5a
commit
383605274c
@ -17,7 +17,11 @@
|
|||||||
package im.vector.matrix.rx
|
package im.vector.matrix.rx
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
import im.vector.matrix.android.api.session.room.model.*
|
import im.vector.matrix.android.api.session.room.members.RoomMemberQueryParams
|
||||||
|
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||||
|
import im.vector.matrix.android.api.session.room.model.ReadReceipt
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
|
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
|
||||||
import im.vector.matrix.android.api.session.room.send.UserDraft
|
import im.vector.matrix.android.api.session.room.send.UserDraft
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
@ -33,9 +37,9 @@ class RxRoom(private val room: Room) {
|
|||||||
.startWith(room.roomSummary().toOptional())
|
.startWith(room.roomSummary().toOptional())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveRoomMembers(memberships: List<Membership>): Observable<List<RoomMember>> {
|
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Observable<List<RoomMember>> {
|
||||||
return room.getRoomMembersLive(memberships).asObservable()
|
return room.getRoomMembersLive(queryParams).asObservable()
|
||||||
.startWith(room.getRoomMembers(memberships))
|
.startWith(room.getRoomMembers(queryParams))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveAnnotationSummary(eventId: String): Observable<Optional<EventAnnotationsSummary>> {
|
fun liveAnnotationSummary(eventId: String): Observable<Optional<EventAnnotationsSummary>> {
|
||||||
|
@ -18,6 +18,7 @@ package im.vector.matrix.rx
|
|||||||
|
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.group.GroupSummaryQueryParams
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.android.api.session.pushers.Pusher
|
import im.vector.matrix.android.api.session.pushers.Pusher
|
||||||
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
||||||
@ -36,9 +37,9 @@ class RxSession(private val session: Session) {
|
|||||||
.startWith(session.getRoomSummaries(queryParams))
|
.startWith(session.getRoomSummaries(queryParams))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveGroupSummaries(): Observable<List<GroupSummary>> {
|
fun liveGroupSummaries(queryParams: GroupSummaryQueryParams): Observable<List<GroupSummary>> {
|
||||||
return session.getGroupSummariesLive().asObservable()
|
return session.getGroupSummariesLive(queryParams).asObservable()
|
||||||
.startWith(session.getGroupSummaries())
|
.startWith(session.getGroupSummaries(queryParams))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveBreadcrumbs(): Observable<List<RoomSummary>> {
|
fun liveBreadcrumbs(): Observable<List<RoomSummary>> {
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.api.query
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic query language. All these cases are mutually exclusive.
|
||||||
|
*/
|
||||||
|
sealed class QueryStringValue {
|
||||||
|
object NoCondition : QueryStringValue()
|
||||||
|
object IsNull : QueryStringValue()
|
||||||
|
object IsNotNull : QueryStringValue()
|
||||||
|
object IsEmpty : QueryStringValue()
|
||||||
|
object IsNotEmpty : QueryStringValue()
|
||||||
|
data class Equals(val string: String, val case: Case) : QueryStringValue()
|
||||||
|
data class Contains(val string: String, val case: Case) : QueryStringValue()
|
||||||
|
|
||||||
|
enum class Case {
|
||||||
|
SENSITIVE,
|
||||||
|
INSENSITIVE
|
||||||
|
}
|
||||||
|
}
|
@ -42,11 +42,11 @@ interface GroupService {
|
|||||||
* Get a list of group summaries.This list is a snapshot of the data.
|
* Get a list of group summaries.This list is a snapshot of the data.
|
||||||
* @return the list of [GroupSummary]
|
* @return the list of [GroupSummary]
|
||||||
*/
|
*/
|
||||||
fun getGroupSummaries(): List<GroupSummary>
|
fun getGroupSummaries(groupSummaryQueryParams: GroupSummaryQueryParams): List<GroupSummary>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a live list of group summaries. This list is refreshed as soon as the data changes.
|
* Get a live list of group summaries. This list is refreshed as soon as the data changes.
|
||||||
* @return the [LiveData] of [GroupSummary]
|
* @return the [LiveData] of [GroupSummary]
|
||||||
*/
|
*/
|
||||||
fun getGroupSummariesLive(): LiveData<List<GroupSummary>>
|
fun getGroupSummariesLive(groupSummaryQueryParams: GroupSummaryQueryParams): LiveData<List<GroupSummary>>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.api.session.group
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
|
||||||
|
fun groupSummaryQueryParams(init: (GroupSummaryQueryParams.Builder.() -> Unit) = {}): GroupSummaryQueryParams {
|
||||||
|
return GroupSummaryQueryParams.Builder().apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class can be used to filter group summaries
|
||||||
|
*/
|
||||||
|
data class GroupSummaryQueryParams(
|
||||||
|
val displayName: QueryStringValue,
|
||||||
|
val memberships: List<Membership>
|
||||||
|
) {
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
|
||||||
|
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
|
||||||
|
var memberships: List<Membership> = Membership.all()
|
||||||
|
|
||||||
|
fun build() = GroupSummaryQueryParams(
|
||||||
|
displayName = displayName,
|
||||||
|
memberships = memberships
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -16,23 +16,33 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.session.room
|
package im.vector.matrix.android.api.session.room
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
|
||||||
|
fun roomSummaryQueryParams(init: (RoomSummaryQueryParams.Builder.() -> Unit) = {}): RoomSummaryQueryParams {
|
||||||
|
return RoomSummaryQueryParams.Builder().apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class can be used to filter room summaries to use with:
|
* This class can be used to filter room summaries to use with:
|
||||||
* [im.vector.matrix.android.api.session.room.Room] and [im.vector.matrix.android.api.session.room.RoomService]
|
* [im.vector.matrix.android.api.session.room.Room] and [im.vector.matrix.android.api.session.room.RoomService]
|
||||||
*/
|
*/
|
||||||
data class RoomSummaryQueryParams(
|
data class RoomSummaryQueryParams(
|
||||||
/**
|
val displayName: QueryStringValue,
|
||||||
* Set to true if you want only non null display name. True by default
|
val canonicalAlias: QueryStringValue,
|
||||||
*/
|
val memberships: List<Membership>
|
||||||
val filterDisplayName: Boolean = true,
|
) {
|
||||||
/**
|
|
||||||
* Set to true if you want only non null canonical alias. False by default.
|
class Builder {
|
||||||
*/
|
|
||||||
val filterCanonicalAlias: Boolean = false,
|
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
|
||||||
/**
|
var canonicalAlias: QueryStringValue = QueryStringValue.NoCondition
|
||||||
* Set the list of memberships you want to filter on. By default, all memberships.
|
var memberships: List<Membership> = Membership.all()
|
||||||
*/
|
|
||||||
val memberships: List<Membership> = Membership.all()
|
fun build() = RoomSummaryQueryParams(
|
||||||
)
|
displayName = displayName,
|
||||||
|
canonicalAlias = canonicalAlias,
|
||||||
|
memberships = memberships
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,7 +18,6 @@ package im.vector.matrix.android.api.session.room.members
|
|||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
|
||||||
@ -41,20 +40,19 @@ interface MembershipService {
|
|||||||
*/
|
*/
|
||||||
fun getRoomMember(userId: String): RoomMember?
|
fun getRoomMember(userId: String): RoomMember?
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the roomMembers of the room filtered by memberships
|
* Return all the roomMembers of the room with params
|
||||||
* @param memberships list of accepted memberships
|
* @param queryParams the params to query for
|
||||||
* @return a roomMember list.
|
* @return a roomMember list.
|
||||||
*/
|
*/
|
||||||
fun getRoomMembers(memberships: List<Membership>): List<RoomMember>
|
fun getRoomMembers(queryParams: RoomMemberQueryParams): List<RoomMember>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the roomMembers of the room filtered by memberships
|
* Return all the roomMembers of the room filtered by memberships
|
||||||
* @param memberships list of accepted memberships
|
* @param queryParams the params to query for
|
||||||
* @return a [LiveData] of roomMember list.
|
* @return a [LiveData] of roomMember list.
|
||||||
*/
|
*/
|
||||||
fun getRoomMembersLive(memberships: List<Membership>): LiveData<List<RoomMember>>
|
fun getRoomMembersLive(queryParams: RoomMemberQueryParams): LiveData<List<RoomMember>>
|
||||||
|
|
||||||
fun getNumberOfJoinedMembers(): Int
|
fun getNumberOfJoinedMembers(): Int
|
||||||
|
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.api.session.room.members
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
|
||||||
|
fun roomMemberQueryParams(init: (RoomMemberQueryParams.Builder.() -> Unit) = {}): RoomMemberQueryParams {
|
||||||
|
return RoomMemberQueryParams.Builder().apply(init).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class can be used to filter room members
|
||||||
|
*/
|
||||||
|
data class RoomMemberQueryParams(
|
||||||
|
val displayName: QueryStringValue,
|
||||||
|
val memberships: List<Membership>
|
||||||
|
) {
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
|
||||||
|
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
|
||||||
|
var memberships: List<Membership> = Membership.all()
|
||||||
|
|
||||||
|
fun build() = RoomMemberQueryParams(
|
||||||
|
displayName = displayName,
|
||||||
|
memberships = memberships
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -49,7 +49,7 @@ enum class Membership(val value: String) {
|
|||||||
return listOf(INVITE, JOIN)
|
return listOf(INVITE, JOIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun all(): List<Membership>{
|
fun all(): List<Membership> {
|
||||||
return values().asList()
|
return values().asList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright 2020 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.
|
||||||
@ -14,12 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.riotx.features.home.room.detail.composer
|
package im.vector.matrix.android.internal.query
|
||||||
|
|
||||||
import im.vector.riotx.core.platform.VectorViewModelAction
|
import io.realm.RealmObject
|
||||||
|
import io.realm.RealmQuery
|
||||||
|
|
||||||
sealed class TextComposerAction : VectorViewModelAction {
|
fun <T : RealmObject, E : Enum<E>> RealmQuery<T>.process(field: String, enums: List<Enum<E>>): RealmQuery<T> {
|
||||||
data class QueryUsers(val query: CharSequence?) : TextComposerAction()
|
val lastEnumValue = enums.lastOrNull()
|
||||||
data class QueryRooms(val query: CharSequence?) : TextComposerAction()
|
this.beginGroup()
|
||||||
data class QueryGroups(val query: CharSequence?) : TextComposerAction()
|
for (enumValue in enums) {
|
||||||
|
this.equalTo(field, enumValue.name)
|
||||||
|
if (enumValue != lastEnumValue) {
|
||||||
|
this.or()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.endGroup()
|
||||||
|
return this
|
||||||
}
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.query
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import io.realm.Case
|
||||||
|
import io.realm.RealmObject
|
||||||
|
import io.realm.RealmQuery
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
fun <T : RealmObject> RealmQuery<T>.process(field: String, queryStringValue: QueryStringValue): RealmQuery<T> {
|
||||||
|
when (queryStringValue) {
|
||||||
|
is QueryStringValue.NoCondition -> Timber.v("No condition to process")
|
||||||
|
is QueryStringValue.IsNotNull -> this.isNotNull(field)
|
||||||
|
is QueryStringValue.IsNull -> this.isNull(field)
|
||||||
|
is QueryStringValue.IsEmpty -> this.isEmpty(field)
|
||||||
|
is QueryStringValue.IsNotEmpty -> this.isNotEmpty(field)
|
||||||
|
is QueryStringValue.Equals -> {
|
||||||
|
this.equalTo(field, queryStringValue.string, queryStringValue.case.toRealmCase())
|
||||||
|
}
|
||||||
|
is QueryStringValue.Contains -> {
|
||||||
|
this.contains(field, queryStringValue.string, queryStringValue.case.toRealmCase())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun QueryStringValue.Case.toRealmCase(): Case {
|
||||||
|
return when (this) {
|
||||||
|
QueryStringValue.Case.INSENSITIVE -> Case.INSENSITIVE
|
||||||
|
QueryStringValue.Case.SENSITIVE -> Case.SENSITIVE
|
||||||
|
}
|
||||||
|
}
|
@ -20,11 +20,13 @@ import androidx.lifecycle.LiveData
|
|||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.session.group.Group
|
import im.vector.matrix.android.api.session.group.Group
|
||||||
import im.vector.matrix.android.api.session.group.GroupService
|
import im.vector.matrix.android.api.session.group.GroupService
|
||||||
|
import im.vector.matrix.android.api.session.group.GroupSummaryQueryParams
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
|
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
|
||||||
import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields
|
import im.vector.matrix.android.internal.database.model.GroupSummaryEntityFields
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
import im.vector.matrix.android.internal.query.process
|
||||||
import im.vector.matrix.android.internal.util.fetchCopyMap
|
import im.vector.matrix.android.internal.util.fetchCopyMap
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
@ -43,22 +45,23 @@ internal class DefaultGroupService @Inject constructor(private val monarchy: Mon
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGroupSummaries(): List<GroupSummary> {
|
override fun getGroupSummaries(groupSummaryQueryParams: GroupSummaryQueryParams): List<GroupSummary> {
|
||||||
return monarchy.fetchAllMappedSync(
|
return monarchy.fetchAllMappedSync(
|
||||||
{ groupSummariesQuery(it) },
|
{ groupSummariesQuery(it, groupSummaryQueryParams) },
|
||||||
{ it.asDomain() }
|
{ it.asDomain() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getGroupSummariesLive(groupSummaryQueryParams: GroupSummaryQueryParams): LiveData<List<GroupSummary>> {
|
||||||
override fun getGroupSummariesLive(): LiveData<List<GroupSummary>> {
|
|
||||||
return monarchy.findAllMappedWithChanges(
|
return monarchy.findAllMappedWithChanges(
|
||||||
{ groupSummariesQuery(it) },
|
{ groupSummariesQuery(it, groupSummaryQueryParams) },
|
||||||
{ it.asDomain() }
|
{ it.asDomain() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun groupSummariesQuery(realm: Realm): RealmQuery<GroupSummaryEntity> {
|
private fun groupSummariesQuery(realm: Realm, queryParams: GroupSummaryQueryParams): RealmQuery<GroupSummaryEntity> {
|
||||||
return GroupSummaryEntity.where(realm).isNotEmpty(GroupSummaryEntityFields.DISPLAY_NAME)
|
return GroupSummaryEntity.where(realm)
|
||||||
|
.process(GroupSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
|
.process(GroupSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ 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
|
||||||
import im.vector.matrix.android.internal.database.query.findByAlias
|
import im.vector.matrix.android.internal.database.query.findByAlias
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
import im.vector.matrix.android.internal.query.process
|
||||||
import im.vector.matrix.android.internal.session.room.alias.GetRoomIdByAliasTask
|
import im.vector.matrix.android.internal.session.room.alias.GetRoomIdByAliasTask
|
||||||
import im.vector.matrix.android.internal.session.room.create.CreateRoomTask
|
import im.vector.matrix.android.internal.session.room.create.CreateRoomTask
|
||||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||||
@ -104,21 +105,9 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona
|
|||||||
|
|
||||||
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||||
val query = RoomSummaryEntity.where(realm)
|
val query = RoomSummaryEntity.where(realm)
|
||||||
if (queryParams.filterCanonicalAlias) {
|
query.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
query.isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
|
query.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
|
||||||
}
|
query.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
if (queryParams.filterCanonicalAlias) {
|
|
||||||
query.isNotEmpty(RoomSummaryEntityFields.CANONICAL_ALIAS)
|
|
||||||
}
|
|
||||||
val lastMembership = queryParams.memberships.lastOrNull()
|
|
||||||
query.beginGroup()
|
|
||||||
for (membership in queryParams.memberships) {
|
|
||||||
query.equalTo(RoomSummaryEntityFields.MEMBERSHIP_STR, membership.name)
|
|
||||||
if (membership != lastMembership) {
|
|
||||||
query.or()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query.endGroup()
|
|
||||||
query.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
|
query.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,14 @@ import com.squareup.inject.assisted.AssistedInject
|
|||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||||
|
import im.vector.matrix.android.api.session.room.members.RoomMemberQueryParams
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.RoomMemberEntity
|
import im.vector.matrix.android.internal.database.model.RoomMemberEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomMemberEntityFields
|
import im.vector.matrix.android.internal.database.model.RoomMemberEntityFields
|
||||||
|
import im.vector.matrix.android.internal.query.process
|
||||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||||
@ -67,10 +69,10 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr
|
|||||||
return roomMemberEntity?.asDomain()
|
return roomMemberEntity?.asDomain()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoomMembers(memberships: List<Membership>): List<RoomMember> {
|
override fun getRoomMembers(queryParams: RoomMemberQueryParams): List<RoomMember> {
|
||||||
return monarchy.fetchAllMappedSync(
|
return monarchy.fetchAllMappedSync(
|
||||||
{
|
{
|
||||||
roomMembersQuery(it, memberships)
|
roomMembersQuery(it, queryParams)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
it.asDomain()
|
it.asDomain()
|
||||||
@ -78,10 +80,10 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoomMembersLive(memberships: List<Membership>): LiveData<List<RoomMember>> {
|
override fun getRoomMembersLive(queryParams: RoomMemberQueryParams): LiveData<List<RoomMember>> {
|
||||||
return monarchy.findAllMappedWithChanges(
|
return monarchy.findAllMappedWithChanges(
|
||||||
{
|
{
|
||||||
roomMembersQuery(it, memberships)
|
roomMembersQuery(it, queryParams)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
it.asDomain()
|
it.asDomain()
|
||||||
@ -89,18 +91,10 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun roomMembersQuery(realm: Realm, memberships: List<Membership>): RealmQuery<RoomMemberEntity> {
|
private fun roomMembersQuery(realm: Realm, queryParams: RoomMemberQueryParams): RealmQuery<RoomMemberEntity> {
|
||||||
val query = RoomMembers(realm, roomId).queryRoomMembersEvent()
|
return RoomMembers(realm, roomId).queryRoomMembersEvent()
|
||||||
val lastMembership = memberships.lastOrNull()
|
.process(RoomMemberEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
query.beginGroup()
|
.process(RoomMemberEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
for (membership in memberships) {
|
|
||||||
query.equalTo(RoomMemberEntityFields.MEMBERSHIP_STR, membership.name)
|
|
||||||
if (membership != lastMembership) {
|
|
||||||
query.or()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query.endGroup()
|
|
||||||
return query
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNumberOfJoinedMembers(): Int {
|
override fun getNumberOfJoinedMembers(): Int {
|
||||||
|
@ -21,7 +21,6 @@ import com.zhuinden.monarchy.Monarchy
|
|||||||
import im.vector.matrix.android.internal.database.helper.deleteOnCascade
|
import im.vector.matrix.android.internal.database.helper.deleteOnCascade
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.task.Task
|
import im.vector.matrix.android.internal.task.Task
|
||||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||||
|
@ -21,8 +21,8 @@ import androidx.lifecycle.LifecycleObserver
|
|||||||
import androidx.lifecycle.OnLifecycleEvent
|
import androidx.lifecycle.OnLifecycleEvent
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import im.vector.matrix.android.api.session.room.roomSummaryQueryParams
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.features.home.HomeRoomListDataSource
|
import im.vector.riotx.features.home.HomeRoomListDataSource
|
||||||
import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID
|
import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID
|
||||||
@ -66,7 +66,8 @@ class AppStateHandler @Inject constructor(
|
|||||||
sessionDataSource.observe()
|
sessionDataSource.observe()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.switchMap {
|
.switchMap {
|
||||||
it.orNull()?.rx()?.liveRoomSummaries(RoomSummaryQueryParams())
|
val query = roomSummaryQueryParams {}
|
||||||
|
it.orNull()?.rx()?.liveRoomSummaries(query)
|
||||||
?: Observable.just(emptyList())
|
?: Observable.just(emptyList())
|
||||||
}
|
}
|
||||||
.throttleLast(300, TimeUnit.MILLISECONDS),
|
.throttleLast(300, TimeUnit.MILLISECONDS),
|
||||||
|
@ -37,10 +37,6 @@ class AutocompleteEmojiController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
fontProvider.addListener(fontProviderListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
var listener: AutocompleteClickListener<String>? = null
|
var listener: AutocompleteClickListener<String>? = null
|
||||||
|
|
||||||
override fun buildModels(data: List<EmojiItem>?) {
|
override fun buildModels(data: List<EmojiItem>?) {
|
||||||
@ -71,6 +67,10 @@ class AutocompleteEmojiController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||||
|
fontProvider.addListener(fontProviderListener)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
|
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
|
||||||
super.onDetachedFromRecyclerView(recyclerView)
|
super.onDetachedFromRecyclerView(recyclerView)
|
||||||
fontProvider.removeListener(fontProviderListener)
|
fontProvider.removeListener(fontProviderListener)
|
||||||
|
@ -19,18 +19,19 @@ package im.vector.riotx.features.autocomplete.group
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.Success
|
|
||||||
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.group.groupSummaryQueryParams
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteGroupPresenter @Inject constructor(context: Context,
|
class AutocompleteGroupPresenter @Inject constructor(context: Context,
|
||||||
private val controller: AutocompleteGroupController
|
private val controller: AutocompleteGroupController,
|
||||||
|
private val session: Session
|
||||||
) : RecyclerViewPresenter<GroupSummary>(context), AutocompleteClickListener<GroupSummary> {
|
) : RecyclerViewPresenter<GroupSummary>(context), AutocompleteClickListener<GroupSummary> {
|
||||||
|
|
||||||
var callback: Callback? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
}
|
}
|
||||||
@ -46,16 +47,20 @@ class AutocompleteGroupPresenter @Inject constructor(context: Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onQuery(query: CharSequence?) {
|
override fun onQuery(query: CharSequence?) {
|
||||||
callback?.onQueryGroups(query)
|
val queryParams = groupSummaryQueryParams {
|
||||||
|
displayName = if (query.isNullOrBlank()) {
|
||||||
|
QueryStringValue.IsNotEmpty
|
||||||
|
} else {
|
||||||
|
QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val groups = session.getGroupSummaries(queryParams)
|
||||||
|
.asSequence()
|
||||||
|
.sortedBy { it.displayName }
|
||||||
|
controller.setData(groups.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(groups: Async<List<GroupSummary>>) {
|
fun render(groups: Async<List<GroupSummary>>) {
|
||||||
if (groups is Success) {
|
|
||||||
controller.setData(groups())
|
controller.setData(groups())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
interface Callback {
|
|
||||||
fun onQueryGroups(query: CharSequence?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,32 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.room.members.roomMemberQueryParams
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class AutocompleteMemberPresenter @Inject constructor(context: Context,
|
class AutocompleteMemberPresenter @AssistedInject constructor(context: Context,
|
||||||
|
@Assisted val roomId: String,
|
||||||
|
private val session: Session,
|
||||||
private val controller: AutocompleteMemberController
|
private val controller: AutocompleteMemberController
|
||||||
) : RecyclerViewPresenter<RoomMember>(context), AutocompleteClickListener<RoomMember> {
|
) : RecyclerViewPresenter<RoomMember>(context), AutocompleteClickListener<RoomMember> {
|
||||||
|
|
||||||
var callback: Callback? = null
|
private val room = session.getRoom(roomId)!!
|
||||||
|
|
||||||
init {
|
init {
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(roomId: String): AutocompleteMemberPresenter
|
||||||
|
}
|
||||||
|
|
||||||
override fun instantiateAdapter(): RecyclerView.Adapter<*> {
|
override fun instantiateAdapter(): RecyclerView.Adapter<*> {
|
||||||
// Also remove animation
|
// Also remove animation
|
||||||
recyclerView?.itemAnimator = null
|
recyclerView?.itemAnimator = null
|
||||||
@ -46,7 +58,18 @@ class AutocompleteMemberPresenter @Inject constructor(context: Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onQuery(query: CharSequence?) {
|
override fun onQuery(query: CharSequence?) {
|
||||||
callback?.onQueryMembers(query)
|
val queryParams = roomMemberQueryParams {
|
||||||
|
displayName = if (query.isNullOrBlank()) {
|
||||||
|
QueryStringValue.IsNotEmpty
|
||||||
|
} else {
|
||||||
|
QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE)
|
||||||
|
}
|
||||||
|
memberships = listOf(Membership.JOIN)
|
||||||
|
}
|
||||||
|
val members = room.getRoomMembers(queryParams)
|
||||||
|
.asSequence()
|
||||||
|
.sortedBy { it.displayName }
|
||||||
|
controller.setData(members.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(members: Async<List<RoomMember>>) {
|
fun render(members: Async<List<RoomMember>>) {
|
||||||
@ -54,8 +77,4 @@ class AutocompleteMemberPresenter @Inject constructor(context: Context,
|
|||||||
controller.setData(members())
|
controller.setData(members())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
|
||||||
fun onQueryMembers(query: CharSequence?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,10 @@ import im.vector.riotx.features.autocomplete.autocompleteMatrixItem
|
|||||||
import im.vector.riotx.features.home.AvatarRenderer
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteRoomController @Inject constructor() : TypedEpoxyController<List<RoomSummary>>() {
|
class AutocompleteRoomController @Inject constructor(private val avatarRenderer: AvatarRenderer) : TypedEpoxyController<List<RoomSummary>>() {
|
||||||
|
|
||||||
var listener: AutocompleteClickListener<RoomSummary>? = null
|
var listener: AutocompleteClickListener<RoomSummary>? = null
|
||||||
|
|
||||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
|
||||||
|
|
||||||
override fun buildModels(data: List<RoomSummary>?) {
|
override fun buildModels(data: List<RoomSummary>?) {
|
||||||
if (data.isNullOrEmpty()) {
|
if (data.isNullOrEmpty()) {
|
||||||
return
|
return
|
||||||
|
@ -18,19 +18,19 @@ package im.vector.riotx.features.autocomplete.room
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.airbnb.mvrx.Async
|
|
||||||
import com.airbnb.mvrx.Success
|
|
||||||
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
import com.otaliastudios.autocomplete.RecyclerViewPresenter
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import im.vector.matrix.android.api.session.room.roomSummaryQueryParams
|
||||||
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteRoomPresenter @Inject constructor(context: Context,
|
class AutocompleteRoomPresenter @Inject constructor(context: Context,
|
||||||
private val controller: AutocompleteRoomController
|
private val controller: AutocompleteRoomController,
|
||||||
|
private val session: Session
|
||||||
) : RecyclerViewPresenter<RoomSummary>(context), AutocompleteClickListener<RoomSummary> {
|
) : RecyclerViewPresenter<RoomSummary>(context), AutocompleteClickListener<RoomSummary> {
|
||||||
|
|
||||||
var callback: Callback? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
}
|
}
|
||||||
@ -46,16 +46,16 @@ class AutocompleteRoomPresenter @Inject constructor(context: Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onQuery(query: CharSequence?) {
|
override fun onQuery(query: CharSequence?) {
|
||||||
callback?.onQueryRooms(query)
|
val queryParams = roomSummaryQueryParams {
|
||||||
}
|
canonicalAlias = if (query.isNullOrBlank()) {
|
||||||
|
QueryStringValue.IsNotNull
|
||||||
fun render(rooms: Async<List<RoomSummary>>) {
|
} else {
|
||||||
if (rooms is Success) {
|
QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE)
|
||||||
controller.setData(rooms())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val rooms = session.getRoomSummaries(queryParams)
|
||||||
interface Callback {
|
.asSequence()
|
||||||
fun onQueryRooms(query: CharSequence?)
|
.sortedBy { it.displayName }
|
||||||
|
controller.setData(rooms.toList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ import com.airbnb.mvrx.MvRxViewModelFactory
|
|||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
|
import im.vector.matrix.android.api.query.QueryStringValue
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.group.groupSummaryQueryParams
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
@ -96,6 +98,10 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeGroupSummaries() {
|
private fun observeGroupSummaries() {
|
||||||
|
val groupSummariesQueryParams = groupSummaryQueryParams {
|
||||||
|
memberships = listOf(Membership.JOIN)
|
||||||
|
displayName = QueryStringValue.IsNotEmpty
|
||||||
|
}
|
||||||
Observable.combineLatest<GroupSummary, List<GroupSummary>, List<GroupSummary>>(
|
Observable.combineLatest<GroupSummary, List<GroupSummary>, List<GroupSummary>>(
|
||||||
session
|
session
|
||||||
.rx()
|
.rx()
|
||||||
@ -109,9 +115,7 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro
|
|||||||
},
|
},
|
||||||
session
|
session
|
||||||
.rx()
|
.rx()
|
||||||
.liveGroupSummaries()
|
.liveGroupSummaries(groupSummariesQueryParams),
|
||||||
// Keep only joined groups. Group invitations will be managed later
|
|
||||||
.map { it.filter { groupSummary -> groupSummary.membership == Membership.JOIN } },
|
|
||||||
BiFunction { allCommunityGroup, communityGroups ->
|
BiFunction { allCommunityGroup, communityGroups ->
|
||||||
listOf(allCommunityGroup) + communityGroups
|
listOf(allCommunityGroup) + communityGroups
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import android.widget.EditText
|
|||||||
import com.otaliastudios.autocomplete.Autocomplete
|
import com.otaliastudios.autocomplete.Autocomplete
|
||||||
import com.otaliastudios.autocomplete.AutocompleteCallback
|
import com.otaliastudios.autocomplete.AutocompleteCallback
|
||||||
import com.otaliastudios.autocomplete.CharPolicy
|
import com.otaliastudios.autocomplete.CharPolicy
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
@ -40,20 +42,25 @@ import im.vector.riotx.features.autocomplete.member.AutocompleteMemberPresenter
|
|||||||
import im.vector.riotx.features.autocomplete.room.AutocompleteRoomPresenter
|
import im.vector.riotx.features.autocomplete.room.AutocompleteRoomPresenter
|
||||||
import im.vector.riotx.features.command.Command
|
import im.vector.riotx.features.command.Command
|
||||||
import im.vector.riotx.features.home.AvatarRenderer
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState
|
|
||||||
import im.vector.riotx.features.html.PillImageSpan
|
import im.vector.riotx.features.html.PillImageSpan
|
||||||
import im.vector.riotx.features.themes.ThemeUtils
|
import im.vector.riotx.features.themes.ThemeUtils
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class AutoCompleter @Inject constructor(
|
class AutoCompleter @AssistedInject constructor(
|
||||||
|
@Assisted val roomId: String,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
||||||
private val autocompleteCommandPresenter: AutocompleteCommandPresenter,
|
private val autocompleteCommandPresenter: AutocompleteCommandPresenter,
|
||||||
private val autocompleteMemberPresenter: AutocompleteMemberPresenter,
|
private val autocompleteMemberPresenter: AutocompleteMemberPresenter.Factory,
|
||||||
private val autocompleteRoomPresenter: AutocompleteRoomPresenter,
|
private val autocompleteRoomPresenter: AutocompleteRoomPresenter,
|
||||||
private val autocompleteGroupPresenter: AutocompleteGroupPresenter,
|
private val autocompleteGroupPresenter: AutocompleteGroupPresenter,
|
||||||
private val autocompleteEmojiPresenter: AutocompleteEmojiPresenter
|
private val autocompleteEmojiPresenter: AutocompleteEmojiPresenter
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(roomId: String): AutoCompleter
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var editText: EditText
|
private lateinit var editText: EditText
|
||||||
|
|
||||||
fun enterSpecialMode() {
|
fun enterSpecialMode() {
|
||||||
@ -68,22 +75,14 @@ class AutoCompleter @Inject constructor(
|
|||||||
GlideApp.with(editText)
|
GlideApp.with(editText)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setup(editText: EditText, listener: AutoCompleterListener) {
|
fun setup(editText: EditText) {
|
||||||
this.editText = editText
|
this.editText = editText
|
||||||
|
|
||||||
val backgroundDrawable = ColorDrawable(ThemeUtils.getColor(editText.context, R.attr.riotx_background))
|
val backgroundDrawable = ColorDrawable(ThemeUtils.getColor(editText.context, R.attr.riotx_background))
|
||||||
|
|
||||||
setupCommands(backgroundDrawable, editText)
|
setupCommands(backgroundDrawable, editText)
|
||||||
setupUsers(backgroundDrawable, editText, listener)
|
setupMembers(backgroundDrawable, editText)
|
||||||
setupRooms(backgroundDrawable, editText, listener)
|
setupGroups(backgroundDrawable, editText)
|
||||||
setupGroups(backgroundDrawable, editText, listener)
|
|
||||||
setupEmojis(backgroundDrawable, editText)
|
setupEmojis(backgroundDrawable, editText)
|
||||||
}
|
setupRooms(backgroundDrawable, editText)
|
||||||
|
|
||||||
fun render(state: TextComposerViewState) {
|
|
||||||
autocompleteMemberPresenter.render(state.asyncMembers)
|
|
||||||
autocompleteRoomPresenter.render(state.asyncRooms)
|
|
||||||
autocompleteGroupPresenter.render(state.asyncGroups)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCommands(backgroundDrawable: Drawable, editText: EditText) {
|
private fun setupCommands(backgroundDrawable: Drawable, editText: EditText) {
|
||||||
@ -107,11 +106,11 @@ class AutoCompleter @Inject constructor(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupUsers(backgroundDrawable: ColorDrawable, editText: EditText, listener: AutocompleteMemberPresenter.Callback) {
|
private fun setupMembers(backgroundDrawable: ColorDrawable, editText: EditText) {
|
||||||
autocompleteMemberPresenter.callback = listener
|
val membersPresenter = autocompleteMemberPresenter.create(roomId)
|
||||||
Autocomplete.on<RoomMember>(editText)
|
Autocomplete.on<RoomMember>(editText)
|
||||||
.with(CharPolicy('@', true))
|
.with(CharPolicy('@', true))
|
||||||
.with(autocompleteMemberPresenter)
|
.with(membersPresenter)
|
||||||
.with(ELEVATION)
|
.with(ELEVATION)
|
||||||
.with(backgroundDrawable)
|
.with(backgroundDrawable)
|
||||||
.with(object : AutocompleteCallback<RoomMember> {
|
.with(object : AutocompleteCallback<RoomMember> {
|
||||||
@ -126,8 +125,7 @@ class AutoCompleter @Inject constructor(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRooms(backgroundDrawable: ColorDrawable, editText: EditText, listener: AutocompleteRoomPresenter.Callback) {
|
private fun setupRooms(backgroundDrawable: ColorDrawable, editText: EditText) {
|
||||||
autocompleteRoomPresenter.callback = listener
|
|
||||||
Autocomplete.on<RoomSummary>(editText)
|
Autocomplete.on<RoomSummary>(editText)
|
||||||
.with(CharPolicy('#', true))
|
.with(CharPolicy('#', true))
|
||||||
.with(autocompleteRoomPresenter)
|
.with(autocompleteRoomPresenter)
|
||||||
@ -145,8 +143,7 @@ class AutoCompleter @Inject constructor(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupGroups(backgroundDrawable: ColorDrawable, editText: EditText, listener: AutocompleteGroupPresenter.Callback) {
|
private fun setupGroups(backgroundDrawable: ColorDrawable, editText: EditText) {
|
||||||
autocompleteGroupPresenter.callback = listener
|
|
||||||
Autocomplete.on<GroupSummary>(editText)
|
Autocomplete.on<GroupSummary>(editText)
|
||||||
.with(CharPolicy('+', true))
|
.with(CharPolicy('+', true))
|
||||||
.with(autocompleteGroupPresenter)
|
.with(autocompleteGroupPresenter)
|
||||||
@ -226,11 +223,6 @@ class AutoCompleter @Inject constructor(
|
|||||||
editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AutoCompleterListener :
|
|
||||||
AutocompleteMemberPresenter.Callback,
|
|
||||||
AutocompleteRoomPresenter.Callback,
|
|
||||||
AutocompleteGroupPresenter.Callback
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ELEVATION = 6f
|
private const val ELEVATION = 6f
|
||||||
}
|
}
|
||||||
|
@ -78,10 +78,7 @@ import im.vector.riotx.features.attachments.ContactAttachment
|
|||||||
import im.vector.riotx.features.command.Command
|
import im.vector.riotx.features.command.Command
|
||||||
import im.vector.riotx.features.home.AvatarRenderer
|
import im.vector.riotx.features.home.AvatarRenderer
|
||||||
import im.vector.riotx.features.home.getColorFromUserId
|
import im.vector.riotx.features.home.getColorFromUserId
|
||||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerAction
|
|
||||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerView
|
import im.vector.riotx.features.home.room.detail.composer.TextComposerView
|
||||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerViewModel
|
|
||||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState
|
|
||||||
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
||||||
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
||||||
import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction
|
import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction
|
||||||
@ -127,17 +124,15 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val timelineEventController: TimelineEventController,
|
private val timelineEventController: TimelineEventController,
|
||||||
private val autoCompleter: AutoCompleter,
|
autoCompleterFactory: AutoCompleter.Factory,
|
||||||
private val permalinkHandler: PermalinkHandler,
|
private val permalinkHandler: PermalinkHandler,
|
||||||
private val notificationDrawerManager: NotificationDrawerManager,
|
private val notificationDrawerManager: NotificationDrawerManager,
|
||||||
val roomDetailViewModelFactory: RoomDetailViewModel.Factory,
|
val roomDetailViewModelFactory: RoomDetailViewModel.Factory,
|
||||||
val textComposerViewModelFactory: TextComposerViewModel.Factory,
|
|
||||||
private val eventHtmlRenderer: EventHtmlRenderer,
|
private val eventHtmlRenderer: EventHtmlRenderer,
|
||||||
private val vectorPreferences: VectorPreferences
|
private val vectorPreferences: VectorPreferences
|
||||||
) :
|
) :
|
||||||
VectorBaseFragment(),
|
VectorBaseFragment(),
|
||||||
TimelineEventController.Callback,
|
TimelineEventController.Callback,
|
||||||
AutoCompleter.AutoCompleterListener,
|
|
||||||
VectorInviteView.Callback,
|
VectorInviteView.Callback,
|
||||||
JumpToReadMarkerView.Callback,
|
JumpToReadMarkerView.Callback,
|
||||||
AttachmentTypeSelectorView.Callback,
|
AttachmentTypeSelectorView.Callback,
|
||||||
@ -167,9 +162,10 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
GlideApp.with(this)
|
GlideApp.with(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val autoCompleter: AutoCompleter by lazy {
|
||||||
|
autoCompleterFactory.create(roomDetailArgs.roomId)
|
||||||
|
}
|
||||||
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
|
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
|
||||||
private val textComposerViewModel: TextComposerViewModel by fragmentViewModel()
|
|
||||||
|
|
||||||
private val debouncer = Debouncer(createUIHandler())
|
private val debouncer = Debouncer(createUIHandler())
|
||||||
|
|
||||||
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
|
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
|
||||||
@ -206,7 +202,6 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
setupJumpToBottomView()
|
setupJumpToBottomView()
|
||||||
|
|
||||||
roomDetailViewModel.subscribe { renderState(it) }
|
roomDetailViewModel.subscribe { renderState(it) }
|
||||||
textComposerViewModel.subscribe { renderTextComposerState(it) }
|
|
||||||
roomDetailViewModel.sendMessageResultLiveData.observeEvent(viewLifecycleOwner) { renderSendMessageResult(it) }
|
roomDetailViewModel.sendMessageResultLiveData.observeEvent(viewLifecycleOwner) { renderSendMessageResult(it) }
|
||||||
|
|
||||||
roomDetailViewModel.nonBlockingPopAlert.observeEvent(this) { pair ->
|
roomDetailViewModel.nonBlockingPopAlert.observeEvent(this) { pair ->
|
||||||
@ -560,7 +555,7 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupComposer() {
|
private fun setupComposer() {
|
||||||
autoCompleter.setup(composerLayout.composerEditText, this)
|
autoCompleter.setup(composerLayout.composerEditText)
|
||||||
composerLayout.callback = object : TextComposerView.Callback {
|
composerLayout.callback = object : TextComposerView.Callback {
|
||||||
override fun onAddAttachment() {
|
override fun onAddAttachment() {
|
||||||
if (!::attachmentTypeSelector.isInitialized) {
|
if (!::attachmentTypeSelector.isInitialized) {
|
||||||
@ -656,10 +651,6 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderTextComposerState(state: TextComposerViewState) {
|
|
||||||
autoCompleter.render(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderTombstoneEventHandling(async: Async<String>) {
|
private fun renderTombstoneEventHandling(async: Async<String>) {
|
||||||
when (async) {
|
when (async) {
|
||||||
is Loading -> {
|
is Loading -> {
|
||||||
@ -984,24 +975,6 @@ class RoomDetailFragment @Inject constructor(
|
|||||||
roomDetailViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState)
|
roomDetailViewModel.handle(RoomDetailAction.EnterTrackingUnreadMessagesState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutocompleteMemberPresenter.Callback
|
|
||||||
|
|
||||||
override fun onQueryMembers(query: CharSequence?) {
|
|
||||||
textComposerViewModel.handle(TextComposerAction.QueryUsers(query))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AutocompleteRoomPresenter.Callback
|
|
||||||
|
|
||||||
override fun onQueryRooms(query: CharSequence?) {
|
|
||||||
textComposerViewModel.handle(TextComposerAction.QueryRooms(query))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AutocompleteGroupPresenter.Callback
|
|
||||||
|
|
||||||
override fun onQueryGroups(query: CharSequence?) {
|
|
||||||
textComposerViewModel.handle(TextComposerAction.QueryGroups(query))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleActions(action: EventSharedAction) {
|
private fun handleActions(action: EventSharedAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is EventSharedAction.AddReaction -> {
|
is EventSharedAction.AddReaction -> {
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.riotx.features.home.room.detail.composer
|
|
||||||
|
|
||||||
import arrow.core.Option
|
|
||||||
import com.airbnb.mvrx.FragmentViewModelContext
|
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
|
||||||
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.RoomSummaryQueryParams
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
|
||||||
import im.vector.matrix.rx.rx
|
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
|
||||||
import im.vector.riotx.features.home.room.detail.RoomDetailFragment
|
|
||||||
import io.reactivex.Observable
|
|
||||||
import io.reactivex.functions.BiFunction
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
typealias AutocompleteQuery = CharSequence
|
|
||||||
|
|
||||||
class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: TextComposerViewState,
|
|
||||||
private val session: Session
|
|
||||||
) : VectorViewModel<TextComposerViewState, TextComposerAction>(initialState) {
|
|
||||||
|
|
||||||
private val room = session.getRoom(initialState.roomId)!!
|
|
||||||
|
|
||||||
private val usersQueryObservable = BehaviorRelay.create<Option<AutocompleteQuery>>()
|
|
||||||
private val roomsQueryObservable = BehaviorRelay.create<Option<AutocompleteQuery>>()
|
|
||||||
private val groupsQueryObservable = BehaviorRelay.create<Option<AutocompleteQuery>>()
|
|
||||||
|
|
||||||
@AssistedInject.Factory
|
|
||||||
interface Factory {
|
|
||||||
fun create(initialState: TextComposerViewState): TextComposerViewModel
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<TextComposerViewModel, TextComposerViewState> {
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel? {
|
|
||||||
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
|
||||||
return fragment.textComposerViewModelFactory.create(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
observeUsersQuery()
|
|
||||||
observeRoomsQuery()
|
|
||||||
observeGroupsQuery()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handle(action: TextComposerAction) {
|
|
||||||
when (action) {
|
|
||||||
is TextComposerAction.QueryUsers -> handleQueryUsers(action)
|
|
||||||
is TextComposerAction.QueryRooms -> handleQueryRooms(action)
|
|
||||||
is TextComposerAction.QueryGroups -> handleQueryGroups(action)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleQueryUsers(action: TextComposerAction.QueryUsers) {
|
|
||||||
val query = Option.fromNullable(action.query)
|
|
||||||
usersQueryObservable.accept(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleQueryRooms(action: TextComposerAction.QueryRooms) {
|
|
||||||
val query = Option.fromNullable(action.query)
|
|
||||||
roomsQueryObservable.accept(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleQueryGroups(action: TextComposerAction.QueryGroups) {
|
|
||||||
val query = Option.fromNullable(action.query)
|
|
||||||
groupsQueryObservable.accept(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun observeUsersQuery() {
|
|
||||||
Observable.combineLatest<List<RoomMember>, Option<AutocompleteQuery>, List<RoomMember>>(
|
|
||||||
room.rx().liveRoomMembers(Membership.activeMemberships()),
|
|
||||||
usersQueryObservable.throttleLast(300, TimeUnit.MILLISECONDS),
|
|
||||||
BiFunction { roomMembers, query ->
|
|
||||||
val filter = query.orNull()
|
|
||||||
if (filter.isNullOrBlank()) {
|
|
||||||
roomMembers
|
|
||||||
} else {
|
|
||||||
roomMembers.filter {
|
|
||||||
it.displayName?.contains(filter, ignoreCase = true) ?: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sortedBy { it.displayName }
|
|
||||||
}
|
|
||||||
).execute { async ->
|
|
||||||
copy(
|
|
||||||
asyncMembers = async
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun observeRoomsQuery() {
|
|
||||||
Observable.combineLatest<List<RoomSummary>, Option<AutocompleteQuery>, List<RoomSummary>>(
|
|
||||||
session.rx().liveRoomSummaries(RoomSummaryQueryParams(filterCanonicalAlias = true)),
|
|
||||||
roomsQueryObservable.throttleLast(300, TimeUnit.MILLISECONDS),
|
|
||||||
BiFunction { roomSummaries, query ->
|
|
||||||
val filter = query.orNull() ?: ""
|
|
||||||
// Keep only room with a canonical alias
|
|
||||||
roomSummaries
|
|
||||||
.filter {
|
|
||||||
it.canonicalAlias?.contains(filter, ignoreCase = true) == true
|
|
||||||
}
|
|
||||||
.sortedBy { it.displayName }
|
|
||||||
}
|
|
||||||
).execute { async ->
|
|
||||||
copy(
|
|
||||||
asyncRooms = async
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun observeGroupsQuery() {
|
|
||||||
Observable.combineLatest<List<GroupSummary>, Option<AutocompleteQuery>, List<GroupSummary>>(
|
|
||||||
session.rx().liveGroupSummaries(),
|
|
||||||
groupsQueryObservable.throttleLast(300, TimeUnit.MILLISECONDS),
|
|
||||||
BiFunction { groupSummaries, query ->
|
|
||||||
val filter = query.orNull()
|
|
||||||
if (filter.isNullOrBlank()) {
|
|
||||||
groupSummaries
|
|
||||||
} else {
|
|
||||||
groupSummaries
|
|
||||||
.filter {
|
|
||||||
it.groupId.contains(filter, ignoreCase = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sortedBy { it.displayName }
|
|
||||||
}
|
|
||||||
).execute { async ->
|
|
||||||
copy(
|
|
||||||
asyncGroups = async
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.riotx.features.home.room.detail.composer
|
|
||||||
|
|
||||||
import com.airbnb.mvrx.Async
|
|
||||||
import com.airbnb.mvrx.MvRxState
|
|
||||||
import com.airbnb.mvrx.Uninitialized
|
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
|
||||||
import im.vector.riotx.features.home.room.detail.RoomDetailArgs
|
|
||||||
|
|
||||||
data class TextComposerViewState(val roomId: String,
|
|
||||||
val asyncMembers: Async<List<RoomMember>> = Uninitialized,
|
|
||||||
val asyncRooms: Async<List<RoomSummary>> = Uninitialized,
|
|
||||||
val asyncGroups: Async<List<GroupSummary>> = Uninitialized
|
|
||||||
) : MvRxState {
|
|
||||||
|
|
||||||
constructor(args: RoomDetailArgs) : this(roomId = args.roomId)
|
|
||||||
}
|
|
@ -18,7 +18,6 @@ package im.vector.riotx.features.reactions.data
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ScreenScope
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -42,6 +41,7 @@ class EmojiDataSource @Inject constructor(
|
|||||||
|
|
||||||
// First add emojis with name matching query, sorted by name
|
// First add emojis with name matching query, sorted by name
|
||||||
return (rawData.emojis.values
|
return (rawData.emojis.values
|
||||||
|
.asSequence()
|
||||||
.filter { emojiItem ->
|
.filter { emojiItem ->
|
||||||
emojiItem.name.contains(query, true)
|
emojiItem.name.contains(query, true)
|
||||||
}
|
}
|
||||||
@ -56,6 +56,7 @@ class EmojiDataSource @Inject constructor(
|
|||||||
.sortedBy { it.name })
|
.sortedBy { it.name })
|
||||||
// and ensure they will not be present twice
|
// and ensure they will not be present twice
|
||||||
.distinct()
|
.distinct()
|
||||||
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getQuickReactions(): List<EmojiItem> {
|
fun getQuickReactions(): List<EmojiItem> {
|
||||||
|
@ -24,12 +24,12 @@ import com.squareup.inject.assisted.AssistedInject
|
|||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsFilter
|
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsFilter
|
||||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||||
import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData
|
import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData
|
||||||
|
import im.vector.matrix.android.api.session.room.roomSummaryQueryParams
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.core.extensions.postLiveEvent
|
import im.vector.riotx.core.extensions.postLiveEvent
|
||||||
@ -80,9 +80,12 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeJoinedRooms() {
|
private fun observeJoinedRooms() {
|
||||||
|
val queryParams = roomSummaryQueryParams {
|
||||||
|
memberships = listOf(Membership.JOIN)
|
||||||
|
}
|
||||||
session
|
session
|
||||||
.rx()
|
.rx()
|
||||||
.liveRoomSummaries(RoomSummaryQueryParams(memberships = listOf(Membership.JOIN)))
|
.liveRoomSummaries(queryParams)
|
||||||
.subscribe { list ->
|
.subscribe { list ->
|
||||||
val joinedRoomIds = list
|
val joinedRoomIds = list
|
||||||
?.map { it.roomId }
|
?.map { it.roomId }
|
||||||
|
@ -23,8 +23,8 @@ import com.squareup.inject.assisted.Assisted
|
|||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.android.api.session.room.roomSummaryQueryParams
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.features.roomdirectory.JoinState
|
import im.vector.riotx.features.roomdirectory.JoinState
|
||||||
@ -54,9 +54,12 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeJoinedRooms() {
|
private fun observeJoinedRooms() {
|
||||||
|
val queryParams = roomSummaryQueryParams {
|
||||||
|
memberships = listOf(Membership.JOIN)
|
||||||
|
}
|
||||||
session
|
session
|
||||||
.rx()
|
.rx()
|
||||||
.liveRoomSummaries(RoomSummaryQueryParams(memberships = listOf(Membership.JOIN)))
|
.liveRoomSummaries(queryParams)
|
||||||
.subscribe { list ->
|
.subscribe { list ->
|
||||||
withState { state ->
|
withState { state ->
|
||||||
val isRoomJoined = list
|
val isRoomJoined = list
|
||||||
|
@ -398,7 +398,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
fun getNotificationRingTone(): Uri? {
|
fun getNotificationRingTone(): Uri? {
|
||||||
val url = defaultPrefs.getString(SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY, null)
|
val url = defaultPrefs.getString(SETTINGS_NOTIFICATION_RINGTONE_PREFERENCE_KEY, null)
|
||||||
|
|
||||||
// the user selects "None"
|
// the user selects "NoCondition"
|
||||||
if (url == "") {
|
if (url == "") {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -425,7 +425,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
/**
|
/**
|
||||||
* Provide the notification ringtone filename
|
* Provide the notification ringtone filename
|
||||||
*
|
*
|
||||||
* @return the filename or null if "None" is selected
|
* @return the filename or null if "NoCondition" is selected
|
||||||
*/
|
*/
|
||||||
fun getNotificationRingToneName(): String? {
|
fun getNotificationRingToneName(): String? {
|
||||||
val toneUri = getNotificationRingTone() ?: return null
|
val toneUri = getNotificationRingTone() ?: return null
|
||||||
|
@ -22,7 +22,7 @@ import com.airbnb.mvrx.MvRxViewModelFactory
|
|||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.squareup.inject.assisted.Assisted
|
import com.squareup.inject.assisted.Assisted
|
||||||
import com.squareup.inject.assisted.AssistedInject
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
|
import im.vector.matrix.android.api.session.room.roomSummaryQueryParams
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotx.ActiveSessionDataSource
|
import im.vector.riotx.ActiveSessionDataSource
|
||||||
import im.vector.riotx.core.platform.EmptyAction
|
import im.vector.riotx.core.platform.EmptyAction
|
||||||
@ -60,10 +60,11 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeRoomSummaries() {
|
private fun observeRoomSummaries() {
|
||||||
|
val queryParams = roomSummaryQueryParams()
|
||||||
sessionObservableStore.observe()
|
sessionObservableStore.observe()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.switchMap {
|
.switchMap {
|
||||||
it.orNull()?.rx()?.liveRoomSummaries(RoomSummaryQueryParams())
|
it.orNull()?.rx()?.liveRoomSummaries(queryParams)
|
||||||
?: Observable.just(emptyList())
|
?: Observable.just(emptyList())
|
||||||
}
|
}
|
||||||
.throttleLast(300, TimeUnit.MILLISECONDS)
|
.throttleLast(300, TimeUnit.MILLISECONDS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user