mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Merge branch 'feature/invites' into develop
This commit is contained in:
commit
2780ca30a8
@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||
@ -78,7 +77,7 @@ object RoomDataHelper {
|
||||
fun fakeInitialSync(monarchy: Monarchy, roomId: String) {
|
||||
monarchy.runTransactionSync { realm ->
|
||||
val roomEntity = realm.createObject<RoomEntity>(roomId)
|
||||
roomEntity.membership = MyMembership.JOINED
|
||||
roomEntity.membership = Membership.JOIN
|
||||
val eventList = createFakeListOfEvents(10)
|
||||
val chunkEntity = realm.createObject<ChunkEntity>().apply {
|
||||
nextToken = null
|
||||
|
@ -21,7 +21,7 @@ import im.vector.matrix.android.InstrumentedTest
|
||||
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.session.room.EventRelationExtractor
|
||||
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
|
||||
|
@ -17,7 +17,7 @@
|
||||
package im.vector.matrix.android.api.session.room
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||
import im.vector.matrix.android.api.session.room.send.SendService
|
||||
@ -27,7 +27,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineService
|
||||
/**
|
||||
* This interface defines methods to interact within a room.
|
||||
*/
|
||||
interface Room : TimelineService, SendService, ReadService, RoomMembersService, StateService {
|
||||
interface Room : TimelineService, SendService, ReadService, MembershipService, StateService {
|
||||
|
||||
/**
|
||||
* The roomId of this room
|
||||
|
@ -24,9 +24,9 @@ import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* This interface defines methods to retrieve room members of a room. It's implemented at the room level.
|
||||
* This interface defines methods to handling membership. It's implemented at the room level.
|
||||
*/
|
||||
interface RoomMembersService {
|
||||
interface MembershipService {
|
||||
|
||||
/**
|
||||
* This methods load all room members if it was done yet.
|
||||
@ -54,4 +54,15 @@ interface RoomMembersService {
|
||||
*/
|
||||
fun invite(userId: String, callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Join the room
|
||||
*/
|
||||
fun join(callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Leave the room.
|
||||
*
|
||||
*/
|
||||
fun leave(callback: MatrixCallback<Unit>)
|
||||
|
||||
}
|
@ -19,10 +19,12 @@ package im.vector.matrix.android.api.session.room.model
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Represents the membership of a user on a room. Linked to a [RoomMember]
|
||||
* Represents the membership of a user on a room
|
||||
*/
|
||||
enum class Membership(val value: String) {
|
||||
|
||||
NONE("none"),
|
||||
|
||||
@Json(name = "invite")
|
||||
INVITE("invite"),
|
||||
|
||||
@ -38,4 +40,8 @@ enum class Membership(val value: String) {
|
||||
@Json(name = "ban")
|
||||
BAN("ban");
|
||||
|
||||
fun isLeft(): Boolean {
|
||||
return this == KNOCK || this == LEAVE || this == BAN
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,27 +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.matrix.android.api.session.room.model
|
||||
|
||||
/**
|
||||
* Represents the membership of the current auth user on a room.
|
||||
*/
|
||||
enum class MyMembership {
|
||||
JOINED,
|
||||
LEFT,
|
||||
INVITED,
|
||||
NONE
|
||||
}
|
@ -31,7 +31,8 @@ data class RoomSummary(
|
||||
val isDirect: Boolean = false,
|
||||
val lastMessage: Event? = null,
|
||||
val otherMemberIds: List<String> = emptyList(),
|
||||
var notificationCount: Int = 0,
|
||||
var highlightCount: Int = 0,
|
||||
var tags: List<RoomTag> = emptyList()
|
||||
val notificationCount: Int = 0,
|
||||
val highlightCount: Int = 0,
|
||||
val tags: List<RoomTag> = emptyList(),
|
||||
val membership: Membership = Membership.NONE
|
||||
)
|
@ -86,10 +86,9 @@ internal fun ChunkEntity.add(roomId: String,
|
||||
isUnlinked: Boolean = false) {
|
||||
|
||||
assertIsManaged()
|
||||
if (event.eventId.isNullOrEmpty() || this.events.fastContains(event.eventId)) {
|
||||
if (event.eventId != null && events.fastContains(event.eventId)) {
|
||||
return
|
||||
}
|
||||
|
||||
var currentDisplayIndex = lastDisplayIndex(direction, 0)
|
||||
if (direction == PaginationDirection.FORWARDS) {
|
||||
currentDisplayIndex += 1
|
||||
|
@ -20,7 +20,7 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.UnsignedData
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
|
||||
import java.util.*
|
||||
|
||||
internal object EventMapper {
|
||||
|
||||
@ -29,7 +29,7 @@ internal object EventMapper {
|
||||
val uds = if (event.unsignedData == null) null
|
||||
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
|
||||
val eventEntity = EventEntity()
|
||||
eventEntity.eventId = event.eventId ?: ""
|
||||
eventEntity.eventId = event.eventId ?: UUID.randomUUID().toString()
|
||||
eventEntity.roomId = event.roomId ?: roomId
|
||||
eventEntity.content = ContentMapper.map(event.content)
|
||||
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent
|
||||
|
@ -37,7 +37,8 @@ internal object RoomSummaryMapper {
|
||||
otherMemberIds = roomSummaryEntity.otherMemberIds.toList(),
|
||||
highlightCount = roomSummaryEntity.highlightCount,
|
||||
notificationCount = roomSummaryEntity.notificationCount,
|
||||
tags = tags
|
||||
tags = tags,
|
||||
membership = roomSummaryEntity.membership
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
import io.realm.annotations.PrimaryKey
|
||||
@ -26,10 +26,10 @@ internal open class GroupEntity(@PrimaryKey var groupId: String = ""
|
||||
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = MyMembership.NONE.name
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: MyMembership by Delegates.observable(MyMembership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
@ -30,10 +30,10 @@ internal open class RoomEntity(@PrimaryKey var roomId: String = "",
|
||||
var areAllMembersLoaded: Boolean = false
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = MyMembership.NONE.name
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: MyMembership by Delegates.observable(MyMembership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,12 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
import io.realm.annotations.PrimaryKey
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
@ -35,6 +38,13 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var tags: RealmList<RoomTagEntity> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntity
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntityFields
|
||||
import io.realm.Realm
|
||||
@ -27,7 +27,7 @@ internal fun GroupEntity.Companion.where(realm: Realm, roomId: String): RealmQue
|
||||
return realm.where<GroupEntity>().equalTo(GroupEntityFields.GROUP_ID, roomId)
|
||||
}
|
||||
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, membership: MyMembership? = null): RealmQuery<GroupEntity> {
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<GroupEntity> {
|
||||
val query = realm.where<GroupEntity>()
|
||||
if (membership != null) {
|
||||
query.equalTo(GroupEntityFields.MEMBERSHIP_STR, membership.name)
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntityFields
|
||||
@ -28,7 +28,7 @@ internal fun RoomEntity.Companion.where(realm: Realm, roomId: String): RealmQuer
|
||||
return realm.where<RoomEntity>().equalTo(RoomEntityFields.ROOM_ID, roomId)
|
||||
}
|
||||
|
||||
internal fun RoomEntity.Companion.where(realm: Realm, membership: MyMembership? = null): RealmQuery<RoomEntity> {
|
||||
internal fun RoomEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<RoomEntity> {
|
||||
val query = realm.where<RoomEntity>()
|
||||
if (membership != null) {
|
||||
query.equalTo(RoomEntityFields.MEMBERSHIP_STR, membership.name)
|
||||
|
@ -37,8 +37,8 @@ import im.vector.matrix.android.internal.session.room.DefaultRoomService
|
||||
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
|
||||
import im.vector.matrix.android.internal.session.room.RoomAvatarResolver
|
||||
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMemberDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.prune.EventsPruner
|
||||
import im.vector.matrix.android.internal.session.signout.DefaultSignOutService
|
||||
import im.vector.matrix.android.internal.session.user.DefaultUserService
|
||||
|
@ -20,7 +20,7 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||
import im.vector.matrix.android.api.session.room.send.SendService
|
||||
@ -39,13 +39,13 @@ internal class DefaultRoom(
|
||||
private val sendService: SendService,
|
||||
private val stateService: StateService,
|
||||
private val readService: ReadService,
|
||||
private val roomMembersService: RoomMembersService
|
||||
private val roomMembersService: MembershipService
|
||||
) : Room,
|
||||
TimelineService by timelineService,
|
||||
SendService by sendService,
|
||||
StateService by stateService,
|
||||
ReadService by readService,
|
||||
RoomMembersService by roomMembersService {
|
||||
TimelineService by timelineService,
|
||||
SendService by sendService,
|
||||
StateService by stateService,
|
||||
ReadService by readService,
|
||||
MembershipService by roomMembersService {
|
||||
|
||||
override val roomSummary: LiveData<RoomSummary> by lazy {
|
||||
val liveRealmData = RealmLiveData<RoomSummaryEntity>(monarchy.realmConfiguration) { realm ->
|
||||
|
@ -18,17 +18,21 @@ package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomResponse
|
||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteBody
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembersResponse
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembersResponse
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteBody
|
||||
import im.vector.matrix.android.internal.session.room.send.SendResponse
|
||||
import im.vector.matrix.android.internal.session.room.timeline.EventContextResponse
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.*
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
internal interface RoomAPI {
|
||||
|
||||
@ -173,4 +177,24 @@ internal interface RoomAPI {
|
||||
@Path("eventType") eventType: String,
|
||||
@Body content: Content?
|
||||
): Call<SendResponse>
|
||||
|
||||
/**
|
||||
* Join the given room.
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param params the request body
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/join")
|
||||
fun join(@Path("roomId") roomId: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
|
||||
/**
|
||||
* Leave the given room.
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param params the request body
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave")
|
||||
fun leave(@Path("roomId") roomId: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
}
|
@ -20,14 +20,14 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomAvatarContent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
|
||||
internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
private val credentials: Credentials) {
|
||||
@ -48,7 +48,7 @@ internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
}
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val members = roomMembers.getLoaded()
|
||||
if (roomEntity?.membership == MyMembership.INVITED) {
|
||||
if (roomEntity?.membership == Membership.INVITE) {
|
||||
if (members.size == 1) {
|
||||
res = members.entries.first().value.avatarUrl
|
||||
} else if (members.size > 1) {
|
||||
@ -57,9 +57,9 @@ internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
}
|
||||
} else {
|
||||
// detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat)
|
||||
if (roomMembers.getNumberOfJoinedMembers() == 1 && members.isNotEmpty()) {
|
||||
if (members.size == 1) {
|
||||
res = members.entries.first().value.avatarUrl
|
||||
} else if (roomMembers.getNumberOfMembers() == 2 && members.size > 1) {
|
||||
} else if (members.size == 2) {
|
||||
val firstOtherMember = members.filterKeys { it != credentials.userId }.values.firstOrNull()
|
||||
res = firstOtherMember?.avatarUrl
|
||||
}
|
||||
|
@ -18,10 +18,12 @@ package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.members.DefaultRoomMembersService
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
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.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.read.DefaultReadService
|
||||
import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.send.DefaultSendService
|
||||
@ -34,24 +36,26 @@ import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
|
||||
internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
internal class RoomFactory(private val monarchy: Monarchy,
|
||||
private val eventFactory: LocalEchoEventFactory,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val monarchy: Monarchy,
|
||||
private val paginationTask: PaginationTask,
|
||||
private val contextOfEventTask: GetContextOfEventTask,
|
||||
private val setReadMarkersTask: SetReadMarkersTask,
|
||||
private val eventFactory: LocalEchoEventFactory,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
private val joinRoomTask: JoinRoomTask,
|
||||
private val leaveRoomTask: LeaveRoomTask) {
|
||||
|
||||
fun instantiate(roomId: String): Room {
|
||||
val roomMemberExtractor = SenderRoomMemberExtractor(roomId)
|
||||
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, EventRelationExtractor())
|
||||
val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, contextOfEventTask, timelineEventFactory, paginationTask)
|
||||
val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, timelineEventFactory, contextOfEventTask, paginationTask)
|
||||
val sendService = DefaultSendService(roomId, eventFactory, monarchy)
|
||||
val stateService = DefaultStateService(roomId, sendStateTask, taskExecutor)
|
||||
val roomMembersService = DefaultRoomMembersService(roomId, monarchy, loadRoomMembersTask, inviteTask, taskExecutor)
|
||||
val readService = DefaultReadService(roomId, monarchy, setReadMarkersTask, taskExecutor)
|
||||
val stateService = DefaultStateService(roomId, taskExecutor, sendStateTask)
|
||||
val roomMembersService = DefaultMembershipService(roomId, monarchy, taskExecutor, loadRoomMembersTask, inviteTask, joinRoomTask, leaveRoomTask)
|
||||
val readService = DefaultReadService(roomId, monarchy, taskExecutor, setReadMarkersTask)
|
||||
|
||||
return DefaultRoom(
|
||||
roomId,
|
||||
|
@ -19,10 +19,14 @@ package im.vector.matrix.android.internal.session.room
|
||||
import im.vector.matrix.android.internal.session.DefaultSession
|
||||
import im.vector.matrix.android.internal.session.room.create.CreateRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.create.DefaultCreateRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.invite.DefaultInviteTask
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.members.DefaultLoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.DefaultLoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.DefaultInviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.DefaultJoinRoomTask
|
||||
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.leaving.DefaultLeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.read.DefaultSetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
|
||||
@ -71,7 +75,7 @@ class RoomModule {
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
@ -82,6 +86,14 @@ class RoomModule {
|
||||
DefaultInviteTask(get()) as InviteTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultJoinRoomTask(get()) as JoinRoomTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultLeaveRoomTask(get()) as LeaveRoomTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultSendStateTask(get()) as SendStateTask
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package im.vector.matrix.android.internal.session.room
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
@ -28,8 +29,8 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.latestEvent
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications
|
||||
import io.realm.Realm
|
||||
@ -41,11 +42,12 @@ internal class RoomSummaryUpdater(private val credentials: Credentials,
|
||||
|
||||
fun update(realm: Realm,
|
||||
roomId: String,
|
||||
membership: Membership? = null,
|
||||
roomSummary: RoomSyncSummary? = null,
|
||||
unreadNotifications: RoomSyncUnreadNotifications? = null) {
|
||||
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
?: realm.createObject(roomId)
|
||||
|
||||
if (roomSummary != null) {
|
||||
if (roomSummary.heroes.isNotEmpty()) {
|
||||
@ -65,8 +67,11 @@ internal class RoomSummaryUpdater(private val credentials: Credentials,
|
||||
if (unreadNotifications?.notificationCount != null) {
|
||||
roomSummaryEntity.notificationCount = unreadNotifications.notificationCount
|
||||
}
|
||||
if (membership != null) {
|
||||
roomSummaryEntity.membership = membership
|
||||
}
|
||||
|
||||
val lastEvent = EventEntity.latestEvent(realm, roomId, includedTypes = listOf(EventType.MESSAGE))
|
||||
val lastEvent = EventEntity.latestEvent(realm, roomId)
|
||||
val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain()
|
||||
val otherRoomMembers = RoomMembers(realm, roomId).getLoaded().filterKeys { it != credentials.userId }
|
||||
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString()
|
||||
|
@ -16,28 +16,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
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.util.Cancelable
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.session.room.invite.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.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.fetchCopied
|
||||
|
||||
internal class DefaultRoomMembersService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : RoomMembersService {
|
||||
internal class DefaultMembershipService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val joinTask: JoinRoomTask,
|
||||
private val leaveRoomTask: LeaveRoomTask
|
||||
) : MembershipService {
|
||||
|
||||
override fun loadRoomMembersIfNeeded(): Cancelable {
|
||||
val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE)
|
||||
@ -68,4 +72,18 @@ internal class DefaultRoomMembersService(private val roomId: String,
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun join(callback: MatrixCallback<Unit>) {
|
||||
val params = JoinRoomTask.Params(roomId)
|
||||
joinTask.configureWith(params)
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun leave(callback: MatrixCallback<Unit>) {
|
||||
val params = LeaveRoomTask.Params(roomId)
|
||||
leaveRoomTask.configureWith(params)
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import arrow.core.Try
|
||||
import com.zhuinden.monarchy.Monarchy
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import android.content.Context
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
@ -22,7 +22,7 @@ import im.vector.matrix.android.R
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||
@ -77,24 +77,17 @@ internal class RoomDisplayNameResolver(private val context: Context,
|
||||
}
|
||||
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val otherRoomMembers = roomMembers.getLoaded()
|
||||
.filterKeys { it != credentials.userId }
|
||||
|
||||
if (roomEntity?.membership == MyMembership.INVITED) {
|
||||
//TODO handle invited
|
||||
/*
|
||||
if (currentUser != null
|
||||
&& !othersActiveMembers.isEmpty()
|
||||
&& !TextUtils.isEmpty(currentUser!!.mSender)) {
|
||||
// extract who invited us to the room
|
||||
name = context.getString(R.string.room_displayname_invite_from, roomState.resolve(currentUser!!.mSender))
|
||||
val loadedMembers = roomMembers.getLoaded()
|
||||
val otherRoomMembers = loadedMembers.filterKeys { it != credentials.userId }
|
||||
if (roomEntity?.membership == Membership.INVITE) {
|
||||
val inviteMeEvent = roomMembers.queryRoomMemberEvent(credentials.userId).findFirst()
|
||||
val inviterId = inviteMeEvent?.sender
|
||||
name = if (inviterId != null && otherRoomMembers.containsKey(inviterId)) {
|
||||
roomMemberDisplayNameResolver.resolve(inviterId, otherRoomMembers)
|
||||
} else {
|
||||
name = context.getString(R.string.room_displayname_room_invite)
|
||||
context.getString(R.string.room_displayname_room_invite)
|
||||
}
|
||||
*/
|
||||
name = context.getString(R.string.room_displayname_room_invite)
|
||||
} else {
|
||||
|
||||
val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
val memberIds = if (roomSummary?.heroes?.isNotEmpty() == true) {
|
||||
roomSummary.heroes
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.invite
|
||||
package im.vector.matrix.android.internal.session.room.membership.joining
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.invite
|
||||
package im.vector.matrix.android.internal.session.room.membership.joining
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.room.membership.joining
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface JoinRoomTask : Task<JoinRoomTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultJoinRoomTask(private val roomAPI: RoomAPI) : JoinRoomTask {
|
||||
|
||||
override fun execute(params: JoinRoomTask.Params): Try<Unit> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.join(params.roomId, HashMap())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.room.membership.leaving
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface LeaveRoomTask : Task<LeaveRoomTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultLeaveRoomTask(private val roomAPI: RoomAPI) : LeaveRoomTask {
|
||||
|
||||
override fun execute(params: LeaveRoomTask.Params): Try<Unit> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.leave(params.roomId, HashMap())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -27,8 +27,8 @@ import im.vector.matrix.android.internal.util.fetchCopied
|
||||
|
||||
internal class DefaultReadService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val setReadMarkersTask: SetReadMarkersTask,
|
||||
private val taskExecutor: TaskExecutor) : ReadService {
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val setReadMarkersTask: SetReadMarkersTask) : ReadService {
|
||||
|
||||
override fun markAllAsRead(callback: MatrixCallback<Unit>) {
|
||||
val latestEvent = getLatestEvent()
|
||||
|
@ -23,8 +23,8 @@ import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
||||
internal class DefaultStateService(private val roomId: String,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val taskExecutor: TaskExecutor) : StateService {
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val sendStateTask: SendStateTask) : StateService {
|
||||
|
||||
override fun updateTopic(topic: String, callback: MatrixCallback<Unit>) {
|
||||
val params = SendStateTask.Params(roomId,
|
||||
|
@ -28,8 +28,8 @@ import im.vector.matrix.android.internal.util.fetchCopyMap
|
||||
internal class DefaultTimelineService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val contextOfEventTask: GetContextOfEventTask,
|
||||
private val timelineEventFactory: TimelineEventFactory,
|
||||
private val contextOfEventTask: GetContextOfEventTask,
|
||||
private val paginationTask: PaginationTask
|
||||
) : TimelineService {
|
||||
|
||||
|
@ -20,7 +20,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.session.room.EventRelationExtractor
|
||||
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
import io.realm.Realm
|
||||
|
||||
internal class TimelineEventFactory(
|
||||
|
@ -17,7 +17,7 @@
|
||||
package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.sync.model.GroupsSyncResponse
|
||||
@ -56,7 +56,7 @@ internal class GroupSyncHandler(private val monarchy: Monarchy) {
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = MyMembership.JOINED
|
||||
groupEntity.membership = Membership.JOIN
|
||||
return groupEntity
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ internal class GroupSyncHandler(private val monarchy: Monarchy) {
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = MyMembership.INVITED
|
||||
groupEntity.membership = Membership.INVITE
|
||||
return groupEntity
|
||||
|
||||
}
|
||||
@ -74,7 +74,7 @@ internal class GroupSyncHandler(private val monarchy: Monarchy) {
|
||||
groupId: String): GroupEntity {
|
||||
|
||||
val groupEntity = GroupEntity.where(realm, groupId).findFirst() ?: GroupEntity(groupId)
|
||||
groupEntity.membership = MyMembership.LEFT
|
||||
groupEntity.membership = Membership.LEAVE
|
||||
return groupEntity
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent
|
||||
import im.vector.matrix.android.internal.database.helper.addAll
|
||||
import im.vector.matrix.android.internal.database.helper.addOrUpdate
|
||||
@ -69,7 +69,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
val rooms = when (handlingStrategy) {
|
||||
is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) }
|
||||
is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) }
|
||||
is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) }
|
||||
is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(realm, it.key, it.value) }
|
||||
}
|
||||
realm.insertOrUpdate(rooms)
|
||||
}
|
||||
@ -83,11 +83,10 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
|
||||
if (roomEntity.membership == MyMembership.INVITED) {
|
||||
if (roomEntity.membership == Membership.INVITE) {
|
||||
roomEntity.chunks.deleteAllFromRealm()
|
||||
}
|
||||
|
||||
roomEntity.membership = MyMembership.JOINED
|
||||
roomEntity.membership = Membership.JOIN
|
||||
|
||||
val lastChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)
|
||||
val isInitialSync = lastChunk == null
|
||||
@ -121,8 +120,8 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
}
|
||||
}
|
||||
}
|
||||
roomSummaryUpdater.update(realm, roomId, roomSync.summary, roomSync.unreadNotifications)
|
||||
eventRelationsAggregationUpdater.update(realm,roomId,roomSync.timeline?.events)
|
||||
eventRelationsAggregationUpdater.update(realm, roomId, roomSync.timeline?.events)
|
||||
roomSummaryUpdater.update(realm, roomId, Membership.JOIN, roomSync.summary, roomSync.unreadNotifications)
|
||||
|
||||
if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) {
|
||||
handleEphemeral(realm, roomId, roomSync.ephemeral)
|
||||
@ -131,7 +130,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) {
|
||||
handleRoomAccountDataEvents(realm, roomId, roomSync.accountData)
|
||||
}
|
||||
|
||||
return roomEntity
|
||||
}
|
||||
|
||||
@ -139,26 +137,28 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
roomId: String,
|
||||
roomSync:
|
||||
InvitedRoomSync): RoomEntity {
|
||||
|
||||
Timber.v("Handle invited sync for room $roomId")
|
||||
|
||||
val roomEntity = RoomEntity()
|
||||
roomEntity.roomId = roomId
|
||||
roomEntity.membership = MyMembership.INVITED
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
roomEntity.membership = Membership.INVITE
|
||||
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
|
||||
val chunkEntity = handleTimelineEvents(realm, roomId, roomSync.inviteState.events)
|
||||
roomEntity.addOrUpdate(chunkEntity)
|
||||
}
|
||||
roomSummaryUpdater.update(realm, roomId, Membership.INVITE)
|
||||
return roomEntity
|
||||
}
|
||||
|
||||
// TODO : handle it
|
||||
private fun handleLeftRoom(roomId: String,
|
||||
private fun handleLeftRoom(realm: Realm,
|
||||
roomId: String,
|
||||
roomSync: RoomSync): RoomEntity {
|
||||
return RoomEntity().apply {
|
||||
this.roomId = roomId
|
||||
this.membership = MyMembership.LEFT
|
||||
}
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
|
||||
roomEntity.membership = Membership.LEAVE
|
||||
roomEntity.chunks.deleteAllFromRealm()
|
||||
roomSummaryUpdater.update(realm, roomId, Membership.LEAVE, roomSync.summary, roomSync.unreadNotifications)
|
||||
return roomEntity
|
||||
}
|
||||
|
||||
private fun handleTimelineEvents(realm: Realm,
|
||||
|
@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.tryTransactionSync
|
||||
|
||||
|
@ -27,9 +27,8 @@ sealed class RoomDetailActions {
|
||||
object IsDisplayed : RoomDetailActions()
|
||||
data class EventDisplayed(val event: TimelineEvent) : RoomDetailActions()
|
||||
data class LoadMore(val direction: Timeline.Direction) : RoomDetailActions()
|
||||
|
||||
data class SendReaction(val reaction: String, val targetEventId: String) : RoomDetailActions()
|
||||
|
||||
|
||||
object AcceptInvite : RoomDetailActions()
|
||||
object RejectInvite : RoomDetailActions()
|
||||
|
||||
}
|
@ -53,7 +53,12 @@ import com.otaliastudios.autocomplete.Autocomplete
|
||||
import com.otaliastudios.autocomplete.AutocompleteCallback
|
||||
import com.otaliastudios.autocomplete.CharPolicy
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.room.model.message.*
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.riotredesign.R
|
||||
@ -64,7 +69,15 @@ import im.vector.riotredesign.core.extensions.observeEvent
|
||||
import im.vector.riotredesign.core.glide.GlideApp
|
||||
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||
import im.vector.riotredesign.core.utils.*
|
||||
import im.vector.riotredesign.core.utils.LiveEvent
|
||||
import im.vector.riotredesign.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
|
||||
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA
|
||||
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA
|
||||
import im.vector.riotredesign.core.utils.checkPermissions
|
||||
import im.vector.riotredesign.core.utils.copyToClipboard
|
||||
import im.vector.riotredesign.core.utils.openCamera
|
||||
import im.vector.riotredesign.core.utils.shareMedia
|
||||
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
||||
import im.vector.riotredesign.features.autocomplete.command.CommandAutocompletePolicy
|
||||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
||||
@ -82,6 +95,7 @@ import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageM
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.EndlessRecyclerViewScrollListener
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.riotredesign.features.html.PillImageSpan
|
||||
import im.vector.riotredesign.features.invite.VectorInviteView
|
||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||
import im.vector.riotredesign.features.media.ImageMediaViewerActivity
|
||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||
@ -112,7 +126,8 @@ private const val REACTION_SELECT_REQUEST_CODE = 2
|
||||
class RoomDetailFragment :
|
||||
VectorBaseFragment(),
|
||||
TimelineEventController.Callback,
|
||||
AutocompleteUserPresenter.Callback {
|
||||
AutocompleteUserPresenter.Callback,
|
||||
VectorInviteView.Callback {
|
||||
|
||||
companion object {
|
||||
|
||||
@ -169,6 +184,7 @@ class RoomDetailFragment :
|
||||
setupToolbar()
|
||||
setupComposer()
|
||||
setupAttachmentButton()
|
||||
setupInviteView()
|
||||
roomDetailViewModel.subscribe { renderState(it) }
|
||||
textComposerViewModel.subscribe { renderTextComposerState(it) }
|
||||
roomDetailViewModel.sendMessageResultLiveData.observeEvent(this) { renderSendMessageResult(it) }
|
||||
@ -183,11 +199,13 @@ class RoomDetailFragment :
|
||||
if (resultCode == RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
REQUEST_FILES_REQUEST_CODE, TAKE_IMAGE_REQUEST_CODE -> handleMediaIntent(data)
|
||||
REACTION_SELECT_REQUEST_CODE -> {
|
||||
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID) ?: return
|
||||
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT) ?: return
|
||||
REACTION_SELECT_REQUEST_CODE -> {
|
||||
val eventId = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_EVENT_ID)
|
||||
?: return
|
||||
val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT)
|
||||
?: return
|
||||
//TODO check if already reacted with that?
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction,eventId))
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction, eventId))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -342,27 +360,31 @@ class RoomDetailFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupInviteView() {
|
||||
inviteView.callback = this
|
||||
}
|
||||
|
||||
private fun onSendChoiceClicked(dialogListItem: DialogListItem) {
|
||||
Timber.v("On send choice clicked: $dialogListItem")
|
||||
when (dialogListItem) {
|
||||
is DialogListItem.SendFile -> {
|
||||
is DialogListItem.SendFile -> {
|
||||
// launchFileIntent
|
||||
}
|
||||
is DialogListItem.SendVoice -> {
|
||||
is DialogListItem.SendVoice -> {
|
||||
//launchAudioRecorderIntent()
|
||||
}
|
||||
is DialogListItem.SendSticker -> {
|
||||
is DialogListItem.SendSticker -> {
|
||||
//startStickerPickerActivity()
|
||||
}
|
||||
is DialogListItem.TakePhotoVideo ->
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
|
||||
// launchCamera()
|
||||
}
|
||||
is DialogListItem.TakePhoto ->
|
||||
is DialogListItem.TakePhoto ->
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA)) {
|
||||
openCamera(requireActivity(), CAMERA_VALUE_TITLE, TAKE_IMAGE_REQUEST_CODE)
|
||||
}
|
||||
is DialogListItem.TakeVideo ->
|
||||
is DialogListItem.TakeVideo ->
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA)) {
|
||||
// launchNativeVideoRecorder()
|
||||
}
|
||||
@ -376,7 +398,17 @@ class RoomDetailFragment :
|
||||
|
||||
private fun renderState(state: RoomDetailViewState) {
|
||||
renderRoomSummary(state)
|
||||
timelineEventController.setTimeline(state.timeline)
|
||||
val summary = state.asyncRoomSummary()
|
||||
val inviter = state.inviter()
|
||||
if (summary?.membership == Membership.JOIN) {
|
||||
timelineEventController.setTimeline(state.timeline)
|
||||
inviteView.visibility = View.GONE
|
||||
} else if (summary?.membership == Membership.INVITE && inviter != null) {
|
||||
inviteView.visibility = View.VISIBLE
|
||||
inviteView.render(inviter, VectorInviteView.Mode.LARGE)
|
||||
} else {
|
||||
//TODO : close the screen
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderRoomSummary(state: RoomDetailViewState) {
|
||||
@ -399,20 +431,20 @@ class RoomDetailFragment :
|
||||
private fun renderSendMessageResult(sendMessageResult: SendMessageResult) {
|
||||
when (sendMessageResult) {
|
||||
is SendMessageResult.MessageSent,
|
||||
is SendMessageResult.SlashCommandHandled -> {
|
||||
is SendMessageResult.SlashCommandHandled -> {
|
||||
// Clear composer
|
||||
composerEditText.text = null
|
||||
}
|
||||
is SendMessageResult.SlashCommandError -> {
|
||||
is SendMessageResult.SlashCommandError -> {
|
||||
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
|
||||
}
|
||||
is SendMessageResult.SlashCommandUnknown -> {
|
||||
is SendMessageResult.SlashCommandUnknown -> {
|
||||
displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command))
|
||||
}
|
||||
is SendMessageResult.SlashCommandResultOk -> {
|
||||
is SendMessageResult.SlashCommandResultOk -> {
|
||||
// Ignore
|
||||
}
|
||||
is SendMessageResult.SlashCommandResultError -> {
|
||||
is SendMessageResult.SlashCommandResultError -> {
|
||||
displayCommandError(sendMessageResult.throwable.localizedMessage)
|
||||
}
|
||||
is SendMessageResult.SlashCommandNotImplemented -> {
|
||||
@ -487,7 +519,7 @@ class RoomDetailFragment :
|
||||
override fun onClickOnReactionPill(informationData: MessageInformationData, reaction: String, on: Boolean) {
|
||||
if (on) {
|
||||
//we should test the current real state of reaction on this event
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction,informationData.eventId))
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction, informationData.eventId))
|
||||
} else {
|
||||
//TODO it's an undo :/
|
||||
}
|
||||
@ -503,18 +535,18 @@ class RoomDetailFragment :
|
||||
it?.getContentIfNotHandled()?.let { actionData ->
|
||||
|
||||
when (actionData.actionId) {
|
||||
MessageMenuViewModel.ACTION_ADD_REACTION -> {
|
||||
MessageMenuViewModel.ACTION_ADD_REACTION -> {
|
||||
val eventId = actionData.data?.toString() ?: return
|
||||
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), eventId), REACTION_SELECT_REQUEST_CODE)
|
||||
}
|
||||
MessageMenuViewModel.ACTION_COPY -> {
|
||||
MessageMenuViewModel.ACTION_COPY -> {
|
||||
//I need info about the current selected message :/
|
||||
copyToClipboard(requireContext(), actionData.data?.toString() ?: "", false)
|
||||
val snack = Snackbar.make(view!!, requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
|
||||
snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
|
||||
snack.show()
|
||||
}
|
||||
MessageMenuViewModel.ACTION_SHARE -> {
|
||||
MessageMenuViewModel.ACTION_SHARE -> {
|
||||
//TODO current data communication is too limited
|
||||
//Need to now the media type
|
||||
actionData.data?.toString()?.let {
|
||||
@ -557,12 +589,12 @@ class RoomDetailFragment :
|
||||
.setPositiveButton(R.string.ok) { dialog, id -> dialog.cancel() }
|
||||
.show()
|
||||
}
|
||||
MessageMenuViewModel.ACTION_QUICK_REACT -> {
|
||||
MessageMenuViewModel.ACTION_QUICK_REACT -> {
|
||||
(actionData.data as? Pair<String, String>)?.let { pairData ->
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(pairData.second, pairData.first))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
@ -615,4 +647,13 @@ class RoomDetailFragment :
|
||||
}
|
||||
}
|
||||
|
||||
// VectorInviteView.Callback
|
||||
|
||||
override fun onAcceptInvite() {
|
||||
roomDetailViewModel.process(RoomDetailActions.AcceptInvite)
|
||||
}
|
||||
|
||||
override fun onRejectInvite() {
|
||||
roomDetailViewModel.process(RoomDetailActions.RejectInvite)
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,13 @@ package im.vector.riotredesign.features.home.room.detail
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||
@ -62,6 +64,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
init {
|
||||
observeRoomSummary()
|
||||
observeEventDisplayedActions()
|
||||
observeInvitationState()
|
||||
room.loadRoomMembersIfNeeded()
|
||||
timeline.start()
|
||||
setState { copy(timeline = this@RoomDetailViewModel.timeline) }
|
||||
@ -69,12 +72,14 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
|
||||
fun process(action: RoomDetailActions) {
|
||||
when (action) {
|
||||
is RoomDetailActions.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailActions.IsDisplayed -> handleIsDisplayed()
|
||||
is RoomDetailActions.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailActions.SendMessage -> handleSendMessage(action)
|
||||
is RoomDetailActions.IsDisplayed -> handleIsDisplayed()
|
||||
is RoomDetailActions.SendMedia -> handleSendMedia(action)
|
||||
is RoomDetailActions.EventDisplayed -> handleEventDisplayed(action)
|
||||
is RoomDetailActions.LoadMore -> handleLoadMore(action)
|
||||
is RoomDetailActions.SendReaction -> handleSendReaction(action)
|
||||
is RoomDetailActions.LoadMore -> handleLoadMore(action)
|
||||
is RoomDetailActions.SendReaction -> handleSendReaction(action)
|
||||
is RoomDetailActions.AcceptInvite -> handleAcceptInvite()
|
||||
is RoomDetailActions.RejectInvite -> handleRejectInvite()
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,63 +94,63 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
val slashCommandResult = CommandParser.parseSplashCommand(action.text)
|
||||
|
||||
when (slashCommandResult) {
|
||||
is ParsedCommand.ErrorNotACommand -> {
|
||||
is ParsedCommand.ErrorNotACommand -> {
|
||||
// Send the text message to the room
|
||||
room.sendTextMessage(action.text)
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
|
||||
}
|
||||
is ParsedCommand.ErrorSyntax -> {
|
||||
is ParsedCommand.ErrorSyntax -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command)))
|
||||
}
|
||||
is ParsedCommand.ErrorEmptySlashCommand -> {
|
||||
is ParsedCommand.ErrorEmptySlashCommand -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown("/")))
|
||||
}
|
||||
is ParsedCommand.ErrorUnknownSlashCommand -> {
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand)))
|
||||
}
|
||||
is ParsedCommand.Invite -> {
|
||||
is ParsedCommand.Invite -> {
|
||||
handleInviteSlashCommand(slashCommandResult)
|
||||
}
|
||||
is ParsedCommand.SetUserPowerLevel -> {
|
||||
is ParsedCommand.SetUserPowerLevel -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.ClearScalarToken -> {
|
||||
is ParsedCommand.ClearScalarToken -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.SetMarkdown -> {
|
||||
is ParsedCommand.SetMarkdown -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.UnbanUser -> {
|
||||
is ParsedCommand.UnbanUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.BanUser -> {
|
||||
is ParsedCommand.BanUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.KickUser -> {
|
||||
is ParsedCommand.KickUser -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.JoinRoom -> {
|
||||
is ParsedCommand.JoinRoom -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.PartRoom -> {
|
||||
is ParsedCommand.PartRoom -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
is ParsedCommand.SendEmote -> {
|
||||
is ParsedCommand.SendEmote -> {
|
||||
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
|
||||
}
|
||||
is ParsedCommand.ChangeTopic -> {
|
||||
is ParsedCommand.ChangeTopic -> {
|
||||
handleChangeTopicSlashCommand(slashCommandResult)
|
||||
}
|
||||
is ParsedCommand.ChangeDisplayName -> {
|
||||
is ParsedCommand.ChangeDisplayName -> {
|
||||
// TODO
|
||||
_sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
|
||||
}
|
||||
@ -182,7 +187,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
|
||||
|
||||
private fun handleSendReaction(action: RoomDetailActions.SendReaction) {
|
||||
room.sendReaction(action.reaction,action.targetEventId)
|
||||
room.sendReaction(action.reaction, action.targetEventId)
|
||||
}
|
||||
|
||||
private fun handleSendMedia(action: RoomDetailActions.SendMedia) {
|
||||
@ -214,6 +219,14 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
timeline.paginate(action.direction, PAGINATION_COUNT)
|
||||
}
|
||||
|
||||
private fun handleRejectInvite() {
|
||||
room.leave(object : MatrixCallback<Unit> {})
|
||||
}
|
||||
|
||||
private fun handleAcceptInvite() {
|
||||
room.join(object : MatrixCallback<Unit> {})
|
||||
}
|
||||
|
||||
private fun observeEventDisplayedActions() {
|
||||
// We are buffering scroll events for one second
|
||||
// and keep the most recent one to set the read receipt on.
|
||||
@ -236,6 +249,18 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeInvitationState() {
|
||||
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
|
||||
if (summary.membership == Membership.INVITE) {
|
||||
summary.lastMessage?.sender?.let { senderId ->
|
||||
session.getUser(senderId)
|
||||
}?.also {
|
||||
setState { copy(inviter = Success(it)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
timeline.dispose()
|
||||
super.onCleared()
|
||||
|
@ -22,11 +22,13 @@ import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineData
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
|
||||
data class RoomDetailViewState(
|
||||
val roomId: String,
|
||||
val eventId: String?,
|
||||
val timeline: Timeline? = null,
|
||||
val inviter: Async<User> = Uninitialized,
|
||||
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val asyncTimelineData: Async<TimelineData> = Uninitialized
|
||||
) : MvRxState {
|
||||
|
@ -24,6 +24,7 @@ import com.airbnb.mvrx.ViewModelContext
|
||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||
import im.vector.matrix.rx.rx
|
||||
@ -153,6 +154,7 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||
}
|
||||
|
||||
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
|
||||
val invites = ArrayList<RoomSummary>()
|
||||
val favourites = ArrayList<RoomSummary>()
|
||||
val directChats = ArrayList<RoomSummary>()
|
||||
val groupRooms = ArrayList<RoomSummary>()
|
||||
@ -160,8 +162,10 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||
val serverNotices = ArrayList<RoomSummary>()
|
||||
|
||||
for (room in rooms) {
|
||||
if (room.membership.isLeft()) continue
|
||||
val tags = room.tags.map { it.name }
|
||||
when {
|
||||
room.membership == Membership.INVITE -> invites.add(room)
|
||||
tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room)
|
||||
tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room)
|
||||
tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room)
|
||||
@ -171,6 +175,7 @@ class RoomListViewModel(initialState: RoomListViewState,
|
||||
}
|
||||
|
||||
return RoomSummaries().apply {
|
||||
put(RoomCategory.INVITE, invites.sortedWith(roomSummaryComparator))
|
||||
put(RoomCategory.FAVOURITE, favourites.sortedWith(roomSummaryComparator))
|
||||
put(RoomCategory.DIRECT, directChats.sortedWith(roomSummaryComparator))
|
||||
put(RoomCategory.GROUP, groupRooms.sortedWith(roomSummaryComparator))
|
||||
|
@ -26,15 +26,17 @@ import im.vector.riotredesign.R
|
||||
data class RoomListViewState(
|
||||
val asyncRooms: Async<RoomSummaries> = Uninitialized,
|
||||
val visibleRoomId: String? = null,
|
||||
val isInviteExpanded: Boolean = true,
|
||||
val isFavouriteRoomsExpanded: Boolean = true,
|
||||
val isDirectRoomsExpanded: Boolean = false,
|
||||
val isGroupRoomsExpanded: Boolean = false,
|
||||
val isLowPriorityRoomsExpanded: Boolean = false,
|
||||
val isServerNoticeRoomsExpanded: Boolean = false
|
||||
val isDirectRoomsExpanded: Boolean = true,
|
||||
val isGroupRoomsExpanded: Boolean = true,
|
||||
val isLowPriorityRoomsExpanded: Boolean = true,
|
||||
val isServerNoticeRoomsExpanded: Boolean = true
|
||||
) : MvRxState {
|
||||
|
||||
fun isCategoryExpanded(roomCategory: RoomCategory): Boolean {
|
||||
return when (roomCategory) {
|
||||
RoomCategory.INVITE -> isInviteExpanded
|
||||
RoomCategory.FAVOURITE -> isFavouriteRoomsExpanded
|
||||
RoomCategory.DIRECT -> isDirectRoomsExpanded
|
||||
RoomCategory.GROUP -> isGroupRoomsExpanded
|
||||
@ -45,6 +47,7 @@ data class RoomListViewState(
|
||||
|
||||
fun toggle(roomCategory: RoomCategory): RoomListViewState {
|
||||
return when (roomCategory) {
|
||||
RoomCategory.INVITE -> copy(isInviteExpanded = !isInviteExpanded)
|
||||
RoomCategory.FAVOURITE -> copy(isFavouriteRoomsExpanded = !isFavouriteRoomsExpanded)
|
||||
RoomCategory.DIRECT -> copy(isDirectRoomsExpanded = !isDirectRoomsExpanded)
|
||||
RoomCategory.GROUP -> copy(isGroupRoomsExpanded = !isGroupRoomsExpanded)
|
||||
@ -57,6 +60,7 @@ data class RoomListViewState(
|
||||
typealias RoomSummaries = LinkedHashMap<RoomCategory, List<RoomSummary>>
|
||||
|
||||
enum class RoomCategory(@StringRes val titleRes: Int) {
|
||||
INVITE(R.string.invitations_header),
|
||||
FAVOURITE(R.string.bottom_action_favourites),
|
||||
DIRECT(R.string.bottom_action_people),
|
||||
GROUP(R.string.bottom_action_rooms),
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.riotredesign.features.invite
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||
import kotlinx.android.synthetic.main.vector_invite_view.view.*
|
||||
|
||||
class VectorInviteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
: ConstraintLayout(context, attrs, defStyle) {
|
||||
|
||||
interface Callback {
|
||||
fun onAcceptInvite()
|
||||
fun onRejectInvite()
|
||||
}
|
||||
|
||||
enum class Mode {
|
||||
LARGE,
|
||||
SMALL
|
||||
}
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
init {
|
||||
View.inflate(context, R.layout.vector_invite_view, this)
|
||||
setBackgroundColor(Color.WHITE)
|
||||
inviteRejectView.setOnClickListener { callback?.onRejectInvite() }
|
||||
inviteAcceptView.setOnClickListener { callback?.onAcceptInvite() }
|
||||
}
|
||||
|
||||
fun render(sender: User, mode: Mode = Mode.LARGE) {
|
||||
if (mode == Mode.LARGE) {
|
||||
updateLayoutParams { height = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT }
|
||||
AvatarRenderer.render(sender.avatarUrl, sender.userId, sender.displayName, inviteAvatarView)
|
||||
inviteIdentifierView.text = sender.userId
|
||||
inviteNameView.text = sender.displayName
|
||||
inviteLabelView.text = context.getString(R.string.send_you_invite)
|
||||
} else {
|
||||
updateLayoutParams { height = ConstraintLayout.LayoutParams.WRAP_CONTENT }
|
||||
inviteAvatarView.visibility = View.GONE
|
||||
inviteIdentifierView.visibility = View.GONE
|
||||
inviteNameView.visibility = View.GONE
|
||||
inviteLabelView.text = context.getString(R.string.invited_by, sender.userId)
|
||||
}
|
||||
}
|
||||
}
|
24
vector/src/main/res/drawable/bg_button_secondary.xml
Normal file
24
vector/src/main/res/drawable/bg_button_secondary.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@android:color/transparent"/>
|
||||
<stroke android:width="1dp" android:color="?attr/colorAccent" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
@ -139,4 +139,16 @@
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<im.vector.riotredesign.features.invite.VectorInviteView
|
||||
android:id="@+id/inviteView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolbar"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
85
vector/src/main/res/layout/vector_invite_view.xml
Normal file
85
vector/src/main/res/layout/vector_invite_view.xml
Normal file
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/inviteAvatarView"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="96dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="86dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inviteNameView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="40dp"
|
||||
android:textAppearance="@style/TextAppearance.Vector.Title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviteAvatarView"
|
||||
tools:text="Matthew" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inviteIdentifierView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/TextAppearance.Vector.Subtitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviteNameView"
|
||||
tools:text="\@matthew:matrix.org" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inviteLabelView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="40dp"
|
||||
android:text="@string/send_you_invite"
|
||||
android:textAppearance="@style/TextAppearance.Vector.Subtitle2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviteIdentifierView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/inviteRejectView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:text="@string/reject"
|
||||
app:layout_constraintEnd_toStartOf="@+id/inviteAcceptView"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviteLabelView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/inviteAcceptView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:text="@string/accept"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toEndOf="@+id/inviteRejectView"
|
||||
app:layout_constraintTop_toTopOf="@id/inviteRejectView" />
|
||||
|
||||
<Space
|
||||
android:layout_height="16dp"
|
||||
android:layout_width="match_parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviteAcceptView"/>
|
||||
|
||||
|
||||
</merge>
|
@ -3,7 +3,6 @@
|
||||
<color name="pale_grey">#f2f5f8</color>
|
||||
<color name="dark">#2e3649</color>
|
||||
<color name="pale_teal">#7ac9a1</color>
|
||||
<color name="black">#212121</color>
|
||||
<color name="deep_sky_blue">#007aff</color>
|
||||
<color name="rosy_pink">#f56679</color>
|
||||
<color name="bluey_grey">#a5a5a6</color>
|
||||
@ -18,4 +17,9 @@
|
||||
<color name="brown_grey">#a5a5a5</color>
|
||||
<color name="grey_lynch">#61708B</color>
|
||||
|
||||
<color name="black">#000000</color>
|
||||
<color name="black_87">#de000000</color>
|
||||
<color name="black_38">#61000000</color>
|
||||
<color name="black_37">#5d000000</color>
|
||||
|
||||
</resources>
|
||||
|
@ -4,6 +4,8 @@
|
||||
<!-- Strings not defined in Riot -->
|
||||
<string name="global_retry">"Retry"</string>
|
||||
<string name="room_list_empty">"Join a room to start using the app."</string>
|
||||
<string name="send_you_invite">"Sent you an invitation"</string>
|
||||
<string name="invited_by">Invited by %s</string>
|
||||
|
||||
|
||||
<string name="title_activity_emoji_reaction_picker">Reactions</string>
|
||||
|
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Button" parent="Widget.AppCompat.Button">
|
||||
<style name="Widget.Vector.Button" parent="Widget.AppCompat.Button">
|
||||
<item name="android:minHeight">48dp</item>
|
||||
<item name="android:background">?attr/colorAccent</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:minWidth">128dp</item>
|
||||
<item name="android:paddingRight">8dp</item>
|
||||
<item name="android:paddingLeft">8dp</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
@ -1,5 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="TextAppearance.Vector.Title" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">@color/black_87</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Vector.Subtitle" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:fontFamily">sans-serif</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">@color/black_37</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Vector.Subtitle2" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
<item name="android:textColor">@color/black_38</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -6,12 +6,14 @@
|
||||
<style name="AppTheme.Base.Light" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
|
||||
<item name="colorPrimaryDark">@color/primary_color_dark_light</item>
|
||||
<item name="colorPrimary">@color/primary_color_light</item>
|
||||
<item name="colorPrimaryVariant">@color/primary_color_dark_light</item>
|
||||
<item name="colorSecondary">@color/accent_color_light</item>
|
||||
<item name="colorOnSecondary">@android:color/white</item>
|
||||
<item name="colorAccent">@color/accent_color_light</item>
|
||||
|
||||
<item name="android:textColorPrimary">@color/primary_text_color_selector_light</item>
|
||||
<item name="android:textColorSecondary">@color/riot_secondary_text_color_light</item>
|
||||
<!-- Default color for text View -->
|
||||
<item name="android:textColorTertiary">@color/riot_tertiary_text_color_light</item>
|
||||
<item name="android:textColorPrimary">@color/black_87</item>
|
||||
<item name="android:textColorSecondary">@color/black_38</item>
|
||||
<item name="android:textColorTertiary">@color/black_37</item>
|
||||
|
||||
<item name="android:textColorLink">@color/link_color_light</item>
|
||||
|
||||
@ -22,6 +24,9 @@
|
||||
<item name="android:colorBackground">@color/riot_primary_background_color_light</item>
|
||||
<item name="vctr_bottom_nav_background_color">#FFF3F8FD</item>
|
||||
|
||||
<!-- default button -->
|
||||
<item name="android:buttonStyle">@style/Widget.Vector.Button</item>
|
||||
|
||||
<!-- waiting view background -->
|
||||
<item name="vctr_waiting_background_color">#AAAAAAAA</item>
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
<item name="vctr_bottom_nav_background_color">@color/riot_primary_background_color_status
|
||||
</item>
|
||||
|
||||
<item name="buttonStyle">@style/Widget.Vector.Button</item>
|
||||
|
||||
<!-- waiting view background -->
|
||||
<item name="vctr_waiting_background_color">#AAAAAAAA</item>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user