mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 20:06:51 +03:00
Merge pull request #5858 from vector-im/feature/bma/room_api
Room now exposes methods to get the various Services
This commit is contained in:
commit
5076b2cdbd
71 changed files with 565 additions and 372 deletions
1
changelog.d/5858.sdk
Normal file
1
changelog.d/5858.sdk
Normal file
|
@ -0,0 +1 @@
|
||||||
|
`Room` apis are now available by requesting the service first. For instance `Room.updateAvatar(...)` is now `Room.stateService().updateAvatar(...)`
|
|
@ -21,6 +21,8 @@ import kotlinx.coroutines.flow.Flow
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
|
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
||||||
|
@ -45,81 +47,81 @@ class FlowRoom(private val room: Room) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Flow<List<RoomMemberSummary>> {
|
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Flow<List<RoomMemberSummary>> {
|
||||||
return room.getRoomMembersLive(queryParams).asFlow()
|
return room.membershipService().getRoomMembersLive(queryParams).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getRoomMembers(queryParams)
|
room.membershipService().getRoomMembers(queryParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveAnnotationSummary(eventId: String): Flow<Optional<EventAnnotationsSummary>> {
|
fun liveAnnotationSummary(eventId: String): Flow<Optional<EventAnnotationsSummary>> {
|
||||||
return room.getEventAnnotationsSummaryLive(eventId).asFlow()
|
return room.relationService().getEventAnnotationsSummaryLive(eventId).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getEventAnnotationsSummary(eventId).toOptional()
|
room.relationService().getEventAnnotationsSummary(eventId).toOptional()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveTimelineEvent(eventId: String): Flow<Optional<TimelineEvent>> {
|
fun liveTimelineEvent(eventId: String): Flow<Optional<TimelineEvent>> {
|
||||||
return room.getTimelineEventLive(eventId).asFlow()
|
return room.timelineService().getTimelineEventLive(eventId).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getTimelineEvent(eventId).toOptional()
|
room.getTimelineEvent(eventId).toOptional()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveStateEvent(eventType: String, stateKey: QueryStringValue): Flow<Optional<Event>> {
|
fun liveStateEvent(eventType: String, stateKey: QueryStringValue): Flow<Optional<Event>> {
|
||||||
return room.getStateEventLive(eventType, stateKey).asFlow()
|
return room.stateService().getStateEventLive(eventType, stateKey).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getStateEvent(eventType, stateKey).toOptional()
|
room.getStateEvent(eventType, stateKey).toOptional()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveStateEvents(eventTypes: Set<String>): Flow<List<Event>> {
|
fun liveStateEvents(eventTypes: Set<String>): Flow<List<Event>> {
|
||||||
return room.getStateEventsLive(eventTypes).asFlow()
|
return room.stateService().getStateEventsLive(eventTypes).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getStateEvents(eventTypes)
|
room.stateService().getStateEvents(eventTypes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveReadMarker(): Flow<Optional<String>> {
|
fun liveReadMarker(): Flow<Optional<String>> {
|
||||||
return room.getReadMarkerLive().asFlow()
|
return room.readService().getReadMarkerLive().asFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveReadReceipt(): Flow<Optional<String>> {
|
fun liveReadReceipt(): Flow<Optional<String>> {
|
||||||
return room.getMyReadReceiptLive().asFlow()
|
return room.readService().getMyReadReceiptLive().asFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveEventReadReceipts(eventId: String): Flow<List<ReadReceipt>> {
|
fun liveEventReadReceipts(eventId: String): Flow<List<ReadReceipt>> {
|
||||||
return room.getEventReadReceiptsLive(eventId).asFlow()
|
return room.readService().getEventReadReceiptsLive(eventId).asFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveDraft(): Flow<Optional<UserDraft>> {
|
fun liveDraft(): Flow<Optional<UserDraft>> {
|
||||||
return room.getDraftLive().asFlow()
|
return room.draftService().getDraftLive().asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getDraft().toOptional()
|
room.draftService().getDraft().toOptional()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveNotificationState(): Flow<RoomNotificationState> {
|
fun liveNotificationState(): Flow<RoomNotificationState> {
|
||||||
return room.getLiveRoomNotificationState().asFlow()
|
return room.roomPushRuleService().getLiveRoomNotificationState().asFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveThreadSummaries(): Flow<List<ThreadSummary>> {
|
fun liveThreadSummaries(): Flow<List<ThreadSummary>> {
|
||||||
return room.getAllThreadSummariesLive().asFlow()
|
return room.threadsService().getAllThreadSummariesLive().asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getAllThreadSummaries()
|
room.threadsService().getAllThreadSummaries()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveThreadList(): Flow<List<ThreadRootEvent>> {
|
fun liveThreadList(): Flow<List<ThreadRootEvent>> {
|
||||||
return room.getAllThreadsLive().asFlow()
|
return room.threadsLocalService().getAllThreadsLive().asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getAllThreads()
|
room.threadsLocalService().getAllThreads()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveLocalUnreadThreadList(): Flow<List<ThreadRootEvent>> {
|
fun liveLocalUnreadThreadList(): Flow<List<ThreadRootEvent>> {
|
||||||
return room.getMarkedThreadNotificationsLive().asFlow()
|
return room.threadsLocalService().getMarkedThreadNotificationsLive().asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
room.getMarkedThreadNotifications()
|
room.threadsLocalService().getMarkedThreadNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ class CommonTestHelper(context: Context) {
|
||||||
* @param nbOfMessages the number of time the message will be sent
|
* @param nbOfMessages the number of time the message will be sent
|
||||||
*/
|
*/
|
||||||
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
||||||
val timeline = room.createTimeline(null, TimelineSettings(10))
|
val timeline = room.timelineService().createTimeline(null, TimelineSettings(10))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
val sentEvents = sendTextMessagesBatched(timeline, room, message, nbOfMessages, timeout)
|
val sentEvents = sendTextMessagesBatched(timeline, room, message, nbOfMessages, timeout)
|
||||||
timeline.dispose()
|
timeline.dispose()
|
||||||
|
@ -165,11 +165,11 @@ class CommonTestHelper(context: Context) {
|
||||||
.forEach { batchedMessages ->
|
.forEach { batchedMessages ->
|
||||||
batchedMessages.forEach { formattedMessage ->
|
batchedMessages.forEach { formattedMessage ->
|
||||||
if (rootThreadEventId != null) {
|
if (rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = rootThreadEventId,
|
rootThreadEventId = rootThreadEventId,
|
||||||
replyInThreadText = formattedMessage)
|
replyInThreadText = formattedMessage)
|
||||||
} else {
|
} else {
|
||||||
room.sendTextMessage(formattedMessage)
|
room.sendService().sendTextMessage(formattedMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitWithLatch(timeout) { latch ->
|
waitWithLatch(timeout) { latch ->
|
||||||
|
@ -214,7 +214,7 @@ class CommonTestHelper(context: Context) {
|
||||||
numberOfMessages: Int,
|
numberOfMessages: Int,
|
||||||
rootThreadEventId: String,
|
rootThreadEventId: String,
|
||||||
timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
||||||
val timeline = room.createTimeline(null, TimelineSettings(10))
|
val timeline = room.timelineService().createTimeline(null, TimelineSettings(10))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
val sentEvents = sendTextMessagesBatched(timeline, room, message, numberOfMessages, timeout, rootThreadEventId)
|
val sentEvents = sendTextMessagesBatched(timeline, room, message, numberOfMessages, timeout, rootThreadEventId)
|
||||||
timeline.dispose()
|
timeline.dispose()
|
||||||
|
|
|
@ -70,7 +70,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
if (encryptedRoom) {
|
if (encryptedRoom) {
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
val room = aliceSession.getRoom(roomId)!!
|
val room = aliceSession.getRoom(roomId)!!
|
||||||
room.enableEncryption()
|
room.roomCryptoService().enableEncryption()
|
||||||
val roomSummaryLive = room.getRoomSummaryLive()
|
val roomSummaryLive = room.getRoomSummaryLive()
|
||||||
val roomSummaryObserver = object : Observer<Optional<RoomSummary>> {
|
val roomSummaryObserver = object : Observer<Optional<RoomSummary>> {
|
||||||
override fun onChanged(roomSummary: Optional<RoomSummary>) {
|
override fun onChanged(roomSummary: Optional<RoomSummary>) {
|
||||||
|
@ -109,7 +109,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bobRoomSummariesLive.observeForever(newRoomObserver)
|
bobRoomSummariesLive.observeForever(newRoomObserver)
|
||||||
aliceRoom.invite(bobSession.myUserId)
|
aliceRoom.membershipService().invite(bobSession.myUserId)
|
||||||
}
|
}
|
||||||
|
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
|
@ -117,6 +117,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
val roomJoinedObserver = object : Observer<List<RoomSummary>> {
|
val roomJoinedObserver = object : Observer<List<RoomSummary>> {
|
||||||
override fun onChanged(t: List<RoomSummary>?) {
|
override fun onChanged(t: List<RoomSummary>?) {
|
||||||
if (bobSession.getRoom(aliceRoomId)
|
if (bobSession.getRoom(aliceRoomId)
|
||||||
|
?.membershipService()
|
||||||
?.getRoomMember(bobSession.myUserId)
|
?.getRoomMember(bobSession.myUserId)
|
||||||
?.membership == Membership.JOIN) {
|
?.membership == Membership.JOIN) {
|
||||||
bobRoomSummariesLive.removeObserver(this)
|
bobRoomSummariesLive.removeObserver(this)
|
||||||
|
@ -161,7 +162,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
val samSession = testHelper.createAccount(TestConstants.USER_SAM, defaultSessionParams)
|
val samSession = testHelper.createAccount(TestConstants.USER_SAM, defaultSessionParams)
|
||||||
|
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
room.invite(samSession.myUserId, null)
|
room.membershipService().invite(samSession.myUserId, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
|
@ -261,6 +262,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
val newRoomObserver = object : Observer<List<RoomSummary>> {
|
val newRoomObserver = object : Observer<List<RoomSummary>> {
|
||||||
override fun onChanged(t: List<RoomSummary>?) {
|
override fun onChanged(t: List<RoomSummary>?) {
|
||||||
if (bob.getRoom(roomId)
|
if (bob.getRoom(roomId)
|
||||||
|
?.membershipService()
|
||||||
?.getRoomMember(bob.myUserId)
|
?.getRoomMember(bob.myUserId)
|
||||||
?.membership == Membership.JOIN) {
|
?.membership == Membership.JOIN) {
|
||||||
bobRoomSummariesLive.removeObserver(this)
|
bobRoomSummariesLive.removeObserver(this)
|
||||||
|
@ -373,13 +375,13 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||||
val room = aliceSession.getRoom(roomId)!!
|
val room = aliceSession.getRoom(roomId)!!
|
||||||
|
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
room.enableEncryption()
|
room.roomCryptoService().enableEncryption()
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessions = mutableListOf(aliceSession)
|
val sessions = mutableListOf(aliceSession)
|
||||||
for (index in 1 until numberOfMembers) {
|
for (index in 1 until numberOfMembers) {
|
||||||
val session = testHelper.createAccount("User_$index", defaultSessionParams)
|
val session = testHelper.createAccount("User_$index", defaultSessionParams)
|
||||||
testHelper.runBlockingTest(timeout = 600_000) { room.invite(session.myUserId, null) }
|
testHelper.runBlockingTest(timeout = 600_000) { room.membershipService().invite(session.myUserId, null) }
|
||||||
println("TEST -> " + session.myUserId + " invited")
|
println("TEST -> " + session.myUserId + " invited")
|
||||||
testHelper.runBlockingTest { session.roomService().joinRoom(room.roomId, null, emptyList()) }
|
testHelper.runBlockingTest { session.roomService().joinRoom(room.roomId, null, emptyList()) }
|
||||||
println("TEST -> " + session.myUserId + " joined")
|
println("TEST -> " + session.myUserId + " joined")
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure
|
import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||||
|
@ -88,7 +89,7 @@ class E2eeSanityTests : InstrumentedTest {
|
||||||
otherAccounts.forEach {
|
otherAccounts.forEach {
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
Log.v("#E2E TEST", "Alice invites ${it.myUserId}")
|
Log.v("#E2E TEST", "Alice invites ${it.myUserId}")
|
||||||
aliceRoomPOV.invite(it.myUserId)
|
aliceRoomPOV.membershipService().invite(it.myUserId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ class E2eeSanityTests : InstrumentedTest {
|
||||||
newAccount.forEach {
|
newAccount.forEach {
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
Log.v("#E2E TEST", "Alice invites ${it.myUserId}")
|
Log.v("#E2E TEST", "Alice invites ${it.myUserId}")
|
||||||
aliceRoomPOV.invite(it.myUserId)
|
aliceRoomPOV.membershipService().invite(it.myUserId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,10 +526,10 @@ class E2eeSanityTests : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendMessageInRoom(aliceRoomPOV: Room, text: String): String? {
|
private fun sendMessageInRoom(aliceRoomPOV: Room, text: String): String? {
|
||||||
aliceRoomPOV.sendTextMessage(text)
|
aliceRoomPOV.sendService().sendTextMessage(text)
|
||||||
var sentEventId: String? = null
|
var sentEventId: String? = null
|
||||||
testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch ->
|
testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch ->
|
||||||
val timeline = aliceRoomPOV.createTimeline(null, TimelineSettings(60))
|
val timeline = aliceRoomPOV.timelineService().createTimeline(null, TimelineSettings(60))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventCon
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent
|
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.common.CommonTestHelper
|
import org.matrix.android.sdk.common.CommonTestHelper
|
||||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||||
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
|
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
|
||||||
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
||||||
|
|
||||||
val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(20))
|
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(20))
|
||||||
bobTimeline.start()
|
bobTimeline.start()
|
||||||
|
|
||||||
val bobFinalLatch = CountDownLatch(1)
|
val bobFinalLatch = CountDownLatch(1)
|
||||||
|
@ -129,7 +129,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||||
messagesReceivedByBob = emptyList()
|
messagesReceivedByBob = emptyList()
|
||||||
|
|
||||||
// - Alice sends a 1st message with a 1st megolm session
|
// - Alice sends a 1st message with a 1st megolm session
|
||||||
roomFromAlicePOV.sendTextMessage("First message")
|
roomFromAlicePOV.sendService().sendTextMessage("First message")
|
||||||
|
|
||||||
// Wait for the message to be received by Bob
|
// Wait for the message to be received by Bob
|
||||||
testHelper.await(latch)
|
testHelper.await(latch)
|
||||||
|
@ -157,7 +157,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||||
|
|
||||||
Timber.i("## CRYPTO | testUnwedging: Alice sends a 2nd message with a 2nd megolm session")
|
Timber.i("## CRYPTO | testUnwedging: Alice sends a 2nd message with a 2nd megolm session")
|
||||||
// - Alice sends a 2nd message with a 2nd megolm session
|
// - Alice sends a 2nd message with a 2nd megolm session
|
||||||
roomFromAlicePOV.sendTextMessage("Second message")
|
roomFromAlicePOV.sendService().sendTextMessage("Second message")
|
||||||
|
|
||||||
// Wait for the message to be received by Bob
|
// Wait for the message to be received by Bob
|
||||||
testHelper.await(latch)
|
testHelper.await(latch)
|
||||||
|
@ -186,7 +186,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||||
|
|
||||||
Timber.i("## CRYPTO | testUnwedging: Alice sends a 3rd message with a 3rd megolm session but a wedged olm session")
|
Timber.i("## CRYPTO | testUnwedging: Alice sends a 3rd message with a 3rd megolm session but a wedged olm session")
|
||||||
// - Alice sends a 3rd message with a 3rd megolm session but a wedged olm session
|
// - Alice sends a 3rd message with a 3rd megolm session but a wedged olm session
|
||||||
roomFromAlicePOV.sendTextMessage("Third message")
|
roomFromAlicePOV.sendService().sendTextMessage("Third message")
|
||||||
// Bob should not be able to decrypt, because the session key could not be sent
|
// Bob should not be able to decrypt, because the session key could not be sent
|
||||||
}
|
}
|
||||||
bobTimeline.removeListener(bobEventsListener)
|
bobTimeline.removeListener(bobEventsListener)
|
||||||
|
|
|
@ -49,7 +49,7 @@ class EncryptionTest : InstrumentedTest {
|
||||||
fun test_EncryptionEvent() {
|
fun test_EncryptionEvent() {
|
||||||
performTest(roomShouldBeEncrypted = false) { room ->
|
performTest(roomShouldBeEncrypted = false) { room ->
|
||||||
// Send an encryption Event as an Event (and not as a state event)
|
// Send an encryption Event as an Event (and not as a state event)
|
||||||
room.sendEvent(
|
room.sendService().sendEvent(
|
||||||
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
||||||
content = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent()
|
content = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent()
|
||||||
)
|
)
|
||||||
|
@ -61,7 +61,7 @@ class EncryptionTest : InstrumentedTest {
|
||||||
performTest(roomShouldBeEncrypted = true) { room ->
|
performTest(roomShouldBeEncrypted = true) { room ->
|
||||||
runBlocking {
|
runBlocking {
|
||||||
// Send an encryption Event as a State Event
|
// Send an encryption Event as a State Event
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
||||||
stateKey = "",
|
stateKey = "",
|
||||||
body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent()
|
body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent()
|
||||||
|
@ -76,9 +76,9 @@ class EncryptionTest : InstrumentedTest {
|
||||||
val aliceSession = cryptoTestData.firstSession
|
val aliceSession = cryptoTestData.firstSession
|
||||||
val room = aliceSession.getRoom(cryptoTestData.roomId)!!
|
val room = aliceSession.getRoom(cryptoTestData.roomId)!!
|
||||||
|
|
||||||
room.isEncrypted() shouldBe false
|
room.roomCryptoService().isEncrypted() shouldBe false
|
||||||
|
|
||||||
val timeline = room.createTimeline(null, TimelineSettings(10))
|
val timeline = room.timelineService().createTimeline(null, TimelineSettings(10))
|
||||||
val latch = CountDownLatch(1)
|
val latch = CountDownLatch(1)
|
||||||
val timelineListener = object : Timeline.Listener {
|
val timelineListener = object : Timeline.Listener {
|
||||||
override fun onTimelineFailure(throwable: Throwable) {
|
override fun onTimelineFailure(throwable: Throwable) {
|
||||||
|
@ -106,7 +106,7 @@ class EncryptionTest : InstrumentedTest {
|
||||||
testHelper.await(latch)
|
testHelper.await(latch)
|
||||||
timeline.dispose()
|
timeline.dispose()
|
||||||
testHelper.waitWithLatch {
|
testHelper.waitWithLatch {
|
||||||
room.isEncrypted() shouldBe roomShouldBeEncrypted
|
room.roomCryptoService().isEncrypted() shouldBe roomShouldBeEncrypted
|
||||||
it.countDown()
|
it.countDown()
|
||||||
}
|
}
|
||||||
cryptoTestData.cleanUp(testHelper)
|
cryptoTestData.cleanUp(testHelper)
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxStat
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
|
@ -84,7 +85,7 @@ class KeyShareTests : InstrumentedTest {
|
||||||
val room = aliceSession.getRoom(roomId)
|
val room = aliceSession.getRoom(roomId)
|
||||||
assertNotNull(room)
|
assertNotNull(room)
|
||||||
Thread.sleep(4_000)
|
Thread.sleep(4_000)
|
||||||
assertTrue(room?.isEncrypted() == true)
|
assertTrue(room?.roomCryptoService()?.isEncrypted() == true)
|
||||||
val sentEventId = commonTestHelper.sendTextMessage(room!!, "My Message", 1).first().eventId
|
val sentEventId = commonTestHelper.sendTextMessage(room!!, "My Message", 1).first().eventId
|
||||||
|
|
||||||
// Open a new sessionx
|
// Open a new sessionx
|
||||||
|
@ -351,7 +352,7 @@ class KeyShareTests : InstrumentedTest {
|
||||||
val roomAlicePov = aliceSession.getRoom(roomId)
|
val roomAlicePov = aliceSession.getRoom(roomId)
|
||||||
assertNotNull(roomAlicePov)
|
assertNotNull(roomAlicePov)
|
||||||
Thread.sleep(1_000)
|
Thread.sleep(1_000)
|
||||||
assertTrue(roomAlicePov?.isEncrypted() == true)
|
assertTrue(roomAlicePov?.roomCryptoService()?.isEncrypted() == true)
|
||||||
val secondEventId = commonTestHelper.sendTextMessage(roomAlicePov!!, "Message", 3)[1].eventId
|
val secondEventId = commonTestHelper.sendTextMessage(roomAlicePov!!, "Message", 3)[1].eventId
|
||||||
|
|
||||||
// Create bob session
|
// Create bob session
|
||||||
|
@ -375,7 +376,7 @@ class KeyShareTests : InstrumentedTest {
|
||||||
|
|
||||||
// Let alice invite bob
|
// Let alice invite bob
|
||||||
commonTestHelper.runBlockingTest {
|
commonTestHelper.runBlockingTest {
|
||||||
roomAlicePov.invite(bobSession.myUserId, null)
|
roomAlicePov.membershipService().invite(bobSession.myUserId, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
commonTestHelper.runBlockingTest {
|
commonTestHelper.runBlockingTest {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventCon
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode
|
import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.common.CommonTestHelper
|
import org.matrix.android.sdk.common.CommonTestHelper
|
||||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||||
import org.matrix.android.sdk.common.MockOkHttpInterceptor
|
import org.matrix.android.sdk.common.MockOkHttpInterceptor
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
replyInThread.root.getRootThreadEventId().shouldBeEqualTo(initMessage.root.eventId)
|
replyInThread.root.getRootThreadEventId().shouldBeEqualTo(initMessage.root.eventId)
|
||||||
|
|
||||||
// The init normal message should now be a root thread event
|
// The init normal message should now be a root thread event
|
||||||
val timeline = aliceRoom.createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.startSync(true)
|
||||||
|
@ -142,7 +142,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
replyInThread.root.getRootThreadEventId().shouldBeEqualTo(initMessage.root.eventId)
|
replyInThread.root.getRootThreadEventId().shouldBeEqualTo(initMessage.root.eventId)
|
||||||
|
|
||||||
// The init normal message should now be a root thread event
|
// The init normal message should now be a root thread event
|
||||||
val timeline = aliceRoom.createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.startSync(true)
|
||||||
|
@ -215,7 +215,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The init normal message should now be a root thread event
|
// The init normal message should now be a root thread event
|
||||||
val timeline = aliceRoom.createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.startSync(true)
|
||||||
|
@ -310,7 +310,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The init normal message should now be a root thread event
|
// The init normal message should now be a root thread event
|
||||||
val timeline = aliceRoom.createTimeline(null, TimelineSettings(30))
|
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.startSync(true)
|
||||||
|
|
|
@ -58,10 +58,10 @@ class PollAggregationTest : InstrumentedTest {
|
||||||
|
|
||||||
val roomFromBobPOV = cryptoTestData.secondSession!!.getRoom(cryptoTestData.roomId)!!
|
val roomFromBobPOV = cryptoTestData.secondSession!!.getRoom(cryptoTestData.roomId)!!
|
||||||
// Bob creates a poll
|
// Bob creates a poll
|
||||||
roomFromBobPOV.sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions)
|
roomFromBobPOV.sendService().sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions)
|
||||||
|
|
||||||
aliceSession.startSync(true)
|
aliceSession.startSync(true)
|
||||||
val aliceTimeline = roomFromAlicePOV.createTimeline(null, TimelineSettings(30))
|
val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
aliceTimeline.start()
|
aliceTimeline.start()
|
||||||
|
|
||||||
val TOTAL_TEST_COUNT = 7
|
val TOTAL_TEST_COUNT = 7
|
||||||
|
@ -84,37 +84,37 @@ class PollAggregationTest : InstrumentedTest {
|
||||||
// Poll has just been created.
|
// Poll has just been created.
|
||||||
testInitialPollConditions(pollContent, pollSummary)
|
testInitialPollConditions(pollContent, pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromBobPOV.voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.firstOrNull()?.id ?: "")
|
roomFromBobPOV.sendService().voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.firstOrNull()?.id ?: "")
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 1 -> {
|
TOTAL_TEST_COUNT - 1 -> {
|
||||||
// Bob: Option 1
|
// Bob: Option 1
|
||||||
testBobVotesOption1(pollContent, pollSummary)
|
testBobVotesOption1(pollContent, pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromBobPOV.voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
roomFromBobPOV.sendService().voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 2 -> {
|
TOTAL_TEST_COUNT - 2 -> {
|
||||||
// Bob: Option 2
|
// Bob: Option 2
|
||||||
testBobChangesVoteToOption2(pollContent, pollSummary)
|
testBobChangesVoteToOption2(pollContent, pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromAlicePOV.voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
roomFromAlicePOV.sendService().voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 3 -> {
|
TOTAL_TEST_COUNT - 3 -> {
|
||||||
// Alice: Option 2, Bob: Option 2
|
// Alice: Option 2, Bob: Option 2
|
||||||
testAliceAndBobVoteToOption2(pollContent, pollSummary)
|
testAliceAndBobVoteToOption2(pollContent, pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromAlicePOV.voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.firstOrNull()?.id ?: "")
|
roomFromAlicePOV.sendService().voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.firstOrNull()?.id ?: "")
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 4 -> {
|
TOTAL_TEST_COUNT - 4 -> {
|
||||||
// Alice: Option 1, Bob: Option 2
|
// Alice: Option 1, Bob: Option 2
|
||||||
testAliceVotesOption1AndBobVotesOption2(pollContent, pollSummary)
|
testAliceVotesOption1AndBobVotesOption2(pollContent, pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromBobPOV.endPoll(pollEventId)
|
roomFromBobPOV.sendService().endPoll(pollEventId)
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 5 -> {
|
TOTAL_TEST_COUNT - 5 -> {
|
||||||
// Alice: Option 1, Bob: Option 2 [poll is ended]
|
// Alice: Option 1, Bob: Option 2 [poll is ended]
|
||||||
testEndedPoll(pollSummary)
|
testEndedPoll(pollSummary)
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
roomFromAlicePOV.voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
roomFromAlicePOV.sendService().voteToPoll(pollEventId, pollContent.getBestPollCreationInfo()?.answers?.get(1)?.id ?: "")
|
||||||
}
|
}
|
||||||
TOTAL_TEST_COUNT - 6 -> {
|
TOTAL_TEST_COUNT - 6 -> {
|
||||||
// Alice: Option 1 (ignore change), Bob: Option 2 [poll is ended]
|
// Alice: Option 1 (ignore change), Bob: Option 2 [poll is ended]
|
||||||
|
|
|
@ -75,7 +75,7 @@ class TimelineForwardPaginationTest : InstrumentedTest {
|
||||||
|
|
||||||
// Alice clear the cache and restart the sync
|
// Alice clear the cache and restart the sync
|
||||||
commonTestHelper.clearCacheAndSync(aliceSession)
|
commonTestHelper.clearCacheAndSync(aliceSession)
|
||||||
val aliceTimeline = roomFromAlicePOV.createTimeline(null, TimelineSettings(30))
|
val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
aliceTimeline.start()
|
aliceTimeline.start()
|
||||||
|
|
||||||
// Alice sees the 10 last message of the room, and can only navigate BACKWARD
|
// Alice sees the 10 last message of the room, and can only navigate BACKWARD
|
||||||
|
|
|
@ -63,7 +63,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||||
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
||||||
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
|
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
|
||||||
|
|
||||||
val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(30))
|
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
bobTimeline.start()
|
bobTimeline.start()
|
||||||
|
|
||||||
run {
|
run {
|
||||||
|
|
|
@ -66,7 +66,7 @@ class TimelineSimpleBackPaginationTest : InstrumentedTest {
|
||||||
message,
|
message,
|
||||||
numberOfMessagesToSent)
|
numberOfMessagesToSent)
|
||||||
|
|
||||||
val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(30))
|
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
bobTimeline.start()
|
bobTimeline.start()
|
||||||
|
|
||||||
commonTestHelper.waitWithLatch(timeout = TestConstants.timeOutMillis * 10) {
|
commonTestHelper.waitWithLatch(timeout = TestConstants.timeOutMillis * 10) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TimelineWithManyMembersTest : InstrumentedTest {
|
||||||
for (index in 1 until cryptoTestData.sessions.size) {
|
for (index in 1 until cryptoTestData.sessions.size) {
|
||||||
val session = cryptoTestData.sessions[index]
|
val session = cryptoTestData.sessions[index]
|
||||||
val roomForCurrentMember = session.getRoom(cryptoTestData.roomId)!!
|
val roomForCurrentMember = session.getRoom(cryptoTestData.roomId)!!
|
||||||
val timelineForCurrentMember = roomForCurrentMember.createTimeline(null, TimelineSettings(30))
|
val timelineForCurrentMember = roomForCurrentMember.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
timelineForCurrentMember.start()
|
timelineForCurrentMember.start()
|
||||||
|
|
||||||
session.startSync(true)
|
session.startSync(true)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.junit.runners.MethodSorters
|
||||||
import org.matrix.android.sdk.InstrumentedTest
|
import org.matrix.android.sdk.InstrumentedTest
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
|
import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
|
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
@ -499,7 +500,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||||
))
|
))
|
||||||
|
|
||||||
commonTestHelper.runBlockingTest {
|
commonTestHelper.runBlockingTest {
|
||||||
aliceSession.getRoom(spaceAInfo.spaceId)!!.invite(bobSession.myUserId, null)
|
aliceSession.getRoom(spaceAInfo.spaceId)!!.membershipService().invite(bobSession.myUserId, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
commonTestHelper.runBlockingTest {
|
commonTestHelper.runBlockingTest {
|
||||||
|
@ -509,7 +510,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||||
var bobRoomId = ""
|
var bobRoomId = ""
|
||||||
commonTestHelper.waitWithLatch {
|
commonTestHelper.waitWithLatch {
|
||||||
bobRoomId = bobSession.roomService().createRoom(CreateRoomParams().apply { name = "A Bob Room" })
|
bobRoomId = bobSession.roomService().createRoom(CreateRoomParams().apply { name = "A Bob Room" })
|
||||||
bobSession.getRoom(bobRoomId)!!.invite(aliceSession.myUserId)
|
bobSession.getRoom(bobRoomId)!!.membershipService().invite(aliceSession.myUserId)
|
||||||
it.countDown()
|
it.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +555,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||||
?.setUserPowerLevel(aliceSession.myUserId, Role.Admin.value)
|
?.setUserPowerLevel(aliceSession.myUserId, Role.Admin.value)
|
||||||
?.toContent()
|
?.toContent()
|
||||||
|
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent!!)
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent!!)
|
||||||
it.countDown()
|
it.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class RoomMemberCountCondition(
|
||||||
// Parse the is field into prefix and number the first time
|
// Parse the is field into prefix and number the first time
|
||||||
val (prefix, count) = parseIsField() ?: return false
|
val (prefix, count) = parseIsField() ?: return false
|
||||||
|
|
||||||
val numMembers = room.getNumberOfJoinedMembers()
|
val numMembers = room.membershipService().getNumberOfJoinedMembers()
|
||||||
|
|
||||||
return when (prefix) {
|
return when (prefix) {
|
||||||
"<" -> numMembers < count
|
"<" -> numMembers < count
|
||||||
|
|
|
@ -44,26 +44,7 @@ import org.matrix.android.sdk.api.util.Optional
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to interact within a room.
|
* This interface defines methods to interact within a room.
|
||||||
*/
|
*/
|
||||||
interface Room :
|
interface Room {
|
||||||
TimelineService,
|
|
||||||
ThreadsService,
|
|
||||||
ThreadsLocalService,
|
|
||||||
SendService,
|
|
||||||
DraftService,
|
|
||||||
ReadService,
|
|
||||||
TypingService,
|
|
||||||
AliasService,
|
|
||||||
TagsService,
|
|
||||||
MembershipService,
|
|
||||||
StateService,
|
|
||||||
UploadsService,
|
|
||||||
ReportingService,
|
|
||||||
RoomCallService,
|
|
||||||
RelationService,
|
|
||||||
RoomCryptoService,
|
|
||||||
RoomPushRuleService,
|
|
||||||
RoomAccountDataService,
|
|
||||||
RoomVersionService {
|
|
||||||
|
|
||||||
val coroutineDispatchers: MatrixCoroutineDispatchers
|
val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||||
|
|
||||||
|
@ -87,4 +68,99 @@ interface Room :
|
||||||
* Use this room as a Space, if the type is correct.
|
* Use this room as a Space, if the type is correct.
|
||||||
*/
|
*/
|
||||||
fun asSpace(): Space?
|
fun asSpace(): Space?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the TimelineService associated to this Room
|
||||||
|
*/
|
||||||
|
fun timelineService(): TimelineService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ThreadsService associated to this Room
|
||||||
|
*/
|
||||||
|
fun threadsService(): ThreadsService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ThreadsLocalService associated to this Room
|
||||||
|
*/
|
||||||
|
fun threadsLocalService(): ThreadsLocalService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the SendService associated to this Room
|
||||||
|
*/
|
||||||
|
fun sendService(): SendService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the DraftService associated to this Room
|
||||||
|
*/
|
||||||
|
fun draftService(): DraftService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ReadService associated to this Room
|
||||||
|
*/
|
||||||
|
fun readService(): ReadService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the TypingService associated to this Room
|
||||||
|
*/
|
||||||
|
fun typingService(): TypingService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the AliasService associated to this Room
|
||||||
|
*/
|
||||||
|
fun aliasService(): AliasService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the TagsService associated to this Room
|
||||||
|
*/
|
||||||
|
fun tagsService(): TagsService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the MembershipService associated to this Room
|
||||||
|
*/
|
||||||
|
fun membershipService(): MembershipService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the StateService associated to this Room
|
||||||
|
*/
|
||||||
|
fun stateService(): StateService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UploadsService associated to this Room
|
||||||
|
*/
|
||||||
|
fun uploadsService(): UploadsService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ReportingService associated to this Room
|
||||||
|
*/
|
||||||
|
fun reportingService(): ReportingService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RoomCallService associated to this Room
|
||||||
|
*/
|
||||||
|
fun roomCallService(): RoomCallService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RelationService associated to this Room
|
||||||
|
*/
|
||||||
|
fun relationService(): RelationService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RoomCryptoService associated to this Room
|
||||||
|
*/
|
||||||
|
fun roomCryptoService(): RoomCryptoService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RoomPushRuleService associated to this Room
|
||||||
|
*/
|
||||||
|
fun roomPushRuleService(): RoomPushRuleService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RoomAccountDataService associated to this Room
|
||||||
|
*/
|
||||||
|
fun roomAccountDataService(): RoomAccountDataService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RoomVersionService associated to this Room
|
||||||
|
*/
|
||||||
|
fun roomVersionService(): RoomVersionService
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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 org.matrix.android.sdk.api.session.room
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a TimelineEvent using the TimelineService of a Room
|
||||||
|
*/
|
||||||
|
fun Room.getTimelineEvent(eventId: String): TimelineEvent? =
|
||||||
|
timelineService().getTimelineEvent(eventId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a StateEvent using the StateService of a Room
|
||||||
|
*/
|
||||||
|
fun Room.getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event? =
|
||||||
|
stateService().getStateEvent(eventType, stateKey)
|
|
@ -72,6 +72,7 @@ internal class ViaParameterFinder @Inject constructor(
|
||||||
*/
|
*/
|
||||||
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
|
private fun getUserIdsOfJoinedMembers(roomId: String): Set<String> {
|
||||||
return roomGetterProvider.get().getRoom(roomId)
|
return roomGetterProvider.get().getRoom(roomId)
|
||||||
|
?.membershipService()
|
||||||
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
||||||
?.map { it.userId }
|
?.map { it.userId }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
@ -84,6 +85,7 @@ internal class ViaParameterFinder @Inject constructor(
|
||||||
// It may not be possible for a user to join a room if there's no overlap between these
|
// It may not be possible for a user to join a room if there's no overlap between these
|
||||||
fun computeViaParamsForRestricted(roomId: String, max: Int): List<String> {
|
fun computeViaParamsForRestricted(roomId: String, max: Int): List<String> {
|
||||||
val userThatCanInvite = roomGetterProvider.get().getRoom(roomId)
|
val userThatCanInvite = roomGetterProvider.get().getRoom(roomId)
|
||||||
|
?.membershipService()
|
||||||
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
|
||||||
?.map { it.userId }
|
?.map { it.userId }
|
||||||
?.filter { userCanInvite(userId, roomId) }
|
?.filter { userCanInvite(userId, roomId) }
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.pushrules.ContainsDisplayNameCondition
|
||||||
import org.matrix.android.sdk.api.session.pushrules.EventMatchCondition
|
import org.matrix.android.sdk.api.session.pushrules.EventMatchCondition
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RoomMemberCountCondition
|
import org.matrix.android.sdk.api.session.pushrules.RoomMemberCountCondition
|
||||||
import org.matrix.android.sdk.api.session.pushrules.SenderNotificationPermissionCondition
|
import org.matrix.android.sdk.api.session.pushrules.SenderNotificationPermissionCondition
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
import org.matrix.android.sdk.internal.session.room.RoomGetter
|
import org.matrix.android.sdk.internal.session.room.RoomGetter
|
||||||
|
@ -60,7 +61,7 @@ internal class DefaultConditionResolver @Inject constructor(
|
||||||
condition: ContainsDisplayNameCondition): Boolean {
|
condition: ContainsDisplayNameCondition): Boolean {
|
||||||
val roomId = event.roomId ?: return false
|
val roomId = event.roomId ?: return false
|
||||||
val room = roomGetter.getRoom(roomId) ?: return false
|
val room = roomGetter.getRoom(roomId) ?: return false
|
||||||
val myDisplayName = room.getRoomMember(userId)?.displayName ?: return false
|
val myDisplayName = room.membershipService().getRoomMember(userId)?.displayName ?: return false
|
||||||
return condition.isSatisfied(event, myDisplayName)
|
return condition.isSatisfied(event, myDisplayName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,11 @@ package org.matrix.android.sdk.internal.session.room
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataService
|
import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataService
|
||||||
import org.matrix.android.sdk.api.session.room.alias.AliasService
|
import org.matrix.android.sdk.api.session.room.alias.AliasService
|
||||||
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
||||||
|
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
||||||
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||||
|
@ -44,57 +42,35 @@ import org.matrix.android.sdk.api.session.room.uploads.UploadsService
|
||||||
import org.matrix.android.sdk.api.session.room.version.RoomVersionService
|
import org.matrix.android.sdk.api.session.room.version.RoomVersionService
|
||||||
import org.matrix.android.sdk.api.session.space.Space
|
import org.matrix.android.sdk.api.session.space.Space
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
|
||||||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||||
import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
|
||||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||||
import org.matrix.android.sdk.internal.session.space.DefaultSpace
|
import org.matrix.android.sdk.internal.session.space.DefaultSpace
|
||||||
import java.security.InvalidParameterException
|
|
||||||
|
|
||||||
internal class DefaultRoom(override val roomId: String,
|
internal class DefaultRoom(
|
||||||
private val roomSummaryDataSource: RoomSummaryDataSource,
|
override val roomId: String,
|
||||||
private val timelineService: TimelineService,
|
private val roomSummaryDataSource: RoomSummaryDataSource,
|
||||||
private val threadsService: ThreadsService,
|
private val roomCryptoService: RoomCryptoService,
|
||||||
private val threadsLocalService: ThreadsLocalService,
|
private val timelineService: TimelineService,
|
||||||
private val sendService: SendService,
|
private val threadsService: ThreadsService,
|
||||||
private val draftService: DraftService,
|
private val threadsLocalService: ThreadsLocalService,
|
||||||
private val stateService: StateService,
|
private val sendService: SendService,
|
||||||
private val uploadsService: UploadsService,
|
private val draftService: DraftService,
|
||||||
private val reportingService: ReportingService,
|
private val stateService: StateService,
|
||||||
private val roomCallService: RoomCallService,
|
private val uploadsService: UploadsService,
|
||||||
private val readService: ReadService,
|
private val reportingService: ReportingService,
|
||||||
private val typingService: TypingService,
|
private val roomCallService: RoomCallService,
|
||||||
private val aliasService: AliasService,
|
private val readService: ReadService,
|
||||||
private val tagsService: TagsService,
|
private val typingService: TypingService,
|
||||||
private val cryptoService: CryptoService,
|
private val aliasService: AliasService,
|
||||||
private val relationService: RelationService,
|
private val tagsService: TagsService,
|
||||||
private val roomMembersService: MembershipService,
|
private val relationService: RelationService,
|
||||||
private val roomPushRuleService: RoomPushRuleService,
|
private val roomMembersService: MembershipService,
|
||||||
private val roomAccountDataService: RoomAccountDataService,
|
private val roomPushRuleService: RoomPushRuleService,
|
||||||
private val roomVersionService: RoomVersionService,
|
private val roomAccountDataService: RoomAccountDataService,
|
||||||
private val sendStateTask: SendStateTask,
|
private val roomVersionService: RoomVersionService,
|
||||||
private val viaParameterFinder: ViaParameterFinder,
|
private val viaParameterFinder: ViaParameterFinder,
|
||||||
override val coroutineDispatchers: MatrixCoroutineDispatchers
|
override val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||||
) :
|
) : Room {
|
||||||
Room,
|
|
||||||
TimelineService by timelineService,
|
|
||||||
ThreadsService by threadsService,
|
|
||||||
ThreadsLocalService by threadsLocalService,
|
|
||||||
SendService by sendService,
|
|
||||||
DraftService by draftService,
|
|
||||||
StateService by stateService,
|
|
||||||
UploadsService by uploadsService,
|
|
||||||
ReportingService by reportingService,
|
|
||||||
RoomCallService by roomCallService,
|
|
||||||
ReadService by readService,
|
|
||||||
TypingService by typingService,
|
|
||||||
AliasService by aliasService,
|
|
||||||
TagsService by tagsService,
|
|
||||||
RelationService by relationService,
|
|
||||||
MembershipService by roomMembersService,
|
|
||||||
RoomPushRuleService by roomPushRuleService,
|
|
||||||
RoomAccountDataService by roomAccountDataService,
|
|
||||||
RoomVersionService by roomVersionService {
|
|
||||||
|
|
||||||
override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> {
|
override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> {
|
||||||
return roomSummaryDataSource.getRoomSummaryLive(roomId)
|
return roomSummaryDataSource.getRoomSummaryLive(roomId)
|
||||||
|
@ -104,49 +80,28 @@ internal class DefaultRoom(override val roomId: String,
|
||||||
return roomSummaryDataSource.getRoomSummary(roomId)
|
return roomSummaryDataSource.getRoomSummary(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isEncrypted(): Boolean {
|
|
||||||
return cryptoService.isRoomEncrypted(roomId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun encryptionAlgorithm(): String? {
|
|
||||||
return cryptoService.getEncryptionAlgorithm(roomId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldEncryptForInvitedMembers(): Boolean {
|
|
||||||
return cryptoService.shouldEncryptForInvitedMembers(roomId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun prepareToEncrypt() {
|
|
||||||
awaitCallback<Unit> {
|
|
||||||
cryptoService.prepareToEncrypt(roomId, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun enableEncryption(algorithm: String, force: Boolean) {
|
|
||||||
when {
|
|
||||||
(!force && isEncrypted() && encryptionAlgorithm() == MXCRYPTO_ALGORITHM_MEGOLM) -> {
|
|
||||||
throw IllegalStateException("Encryption is already enabled for this room")
|
|
||||||
}
|
|
||||||
(!force && algorithm != MXCRYPTO_ALGORITHM_MEGOLM) -> {
|
|
||||||
throw InvalidParameterException("Only MXCRYPTO_ALGORITHM_MEGOLM algorithm is supported")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
val params = SendStateTask.Params(
|
|
||||||
roomId = roomId,
|
|
||||||
stateKey = "",
|
|
||||||
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
|
||||||
body = mapOf(
|
|
||||||
"algorithm" to algorithm
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
sendStateTask.execute(params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun asSpace(): Space? {
|
override fun asSpace(): Space? {
|
||||||
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
||||||
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun timelineService() = timelineService
|
||||||
|
override fun threadsService() = threadsService
|
||||||
|
override fun threadsLocalService() = threadsLocalService
|
||||||
|
override fun sendService() = sendService
|
||||||
|
override fun draftService() = draftService
|
||||||
|
override fun stateService() = stateService
|
||||||
|
override fun uploadsService() = uploadsService
|
||||||
|
override fun reportingService() = reportingService
|
||||||
|
override fun roomCallService() = roomCallService
|
||||||
|
override fun readService() = readService
|
||||||
|
override fun typingService() = typingService
|
||||||
|
override fun aliasService() = aliasService
|
||||||
|
override fun tagsService() = tagsService
|
||||||
|
override fun relationService() = relationService
|
||||||
|
override fun roomCryptoService() = roomCryptoService
|
||||||
|
override fun membershipService() = roomMembersService
|
||||||
|
override fun roomPushRuleService() = roomPushRuleService
|
||||||
|
override fun roomAccountDataService() = roomAccountDataService
|
||||||
|
override fun roomVersionService() = roomVersionService
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventCon
|
||||||
import org.matrix.android.sdk.api.session.events.model.getRelationContent
|
import org.matrix.android.sdk.api.session.events.model.getRelationContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PollSummaryContent
|
import org.matrix.android.sdk.api.session.room.model.PollSummaryContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedContent
|
import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedContent
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
package org.matrix.android.sdk.internal.session.room
|
package org.matrix.android.sdk.internal.session.room
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder
|
||||||
import org.matrix.android.sdk.internal.session.room.accountdata.DefaultRoomAccountDataService
|
import org.matrix.android.sdk.internal.session.room.accountdata.DefaultRoomAccountDataService
|
||||||
import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService
|
import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService
|
||||||
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
|
import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService
|
||||||
|
import org.matrix.android.sdk.internal.session.room.crypto.DefaultRoomCryptoService
|
||||||
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
|
import org.matrix.android.sdk.internal.session.room.draft.DefaultDraftService
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.DefaultMembershipService
|
import org.matrix.android.sdk.internal.session.room.membership.DefaultMembershipService
|
||||||
import org.matrix.android.sdk.internal.session.room.notification.DefaultRoomPushRuleService
|
import org.matrix.android.sdk.internal.session.room.notification.DefaultRoomPushRuleService
|
||||||
|
@ -32,7 +32,6 @@ import org.matrix.android.sdk.internal.session.room.relation.DefaultRelationServ
|
||||||
import org.matrix.android.sdk.internal.session.room.reporting.DefaultReportingService
|
import org.matrix.android.sdk.internal.session.room.reporting.DefaultReportingService
|
||||||
import org.matrix.android.sdk.internal.session.room.send.DefaultSendService
|
import org.matrix.android.sdk.internal.session.room.send.DefaultSendService
|
||||||
import org.matrix.android.sdk.internal.session.room.state.DefaultStateService
|
import org.matrix.android.sdk.internal.session.room.state.DefaultStateService
|
||||||
import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
|
||||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||||
import org.matrix.android.sdk.internal.session.room.tags.DefaultTagsService
|
import org.matrix.android.sdk.internal.session.room.tags.DefaultTagsService
|
||||||
import org.matrix.android.sdk.internal.session.room.threads.DefaultThreadsService
|
import org.matrix.android.sdk.internal.session.room.threads.DefaultThreadsService
|
||||||
|
@ -48,35 +47,36 @@ internal interface RoomFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
internal class DefaultRoomFactory @Inject constructor(private val cryptoService: CryptoService,
|
internal class DefaultRoomFactory @Inject constructor(
|
||||||
private val roomSummaryDataSource: RoomSummaryDataSource,
|
private val roomSummaryDataSource: RoomSummaryDataSource,
|
||||||
private val timelineServiceFactory: DefaultTimelineService.Factory,
|
private val timelineServiceFactory: DefaultTimelineService.Factory,
|
||||||
private val threadsServiceFactory: DefaultThreadsService.Factory,
|
private val threadsServiceFactory: DefaultThreadsService.Factory,
|
||||||
private val threadsLocalServiceFactory: DefaultThreadsLocalService.Factory,
|
private val threadsLocalServiceFactory: DefaultThreadsLocalService.Factory,
|
||||||
private val sendServiceFactory: DefaultSendService.Factory,
|
private val sendServiceFactory: DefaultSendService.Factory,
|
||||||
private val draftServiceFactory: DefaultDraftService.Factory,
|
private val draftServiceFactory: DefaultDraftService.Factory,
|
||||||
private val stateServiceFactory: DefaultStateService.Factory,
|
private val stateServiceFactory: DefaultStateService.Factory,
|
||||||
private val uploadsServiceFactory: DefaultUploadsService.Factory,
|
private val uploadsServiceFactory: DefaultUploadsService.Factory,
|
||||||
private val reportingServiceFactory: DefaultReportingService.Factory,
|
private val reportingServiceFactory: DefaultReportingService.Factory,
|
||||||
private val roomCallServiceFactory: DefaultRoomCallService.Factory,
|
private val roomCallServiceFactory: DefaultRoomCallService.Factory,
|
||||||
private val readServiceFactory: DefaultReadService.Factory,
|
private val readServiceFactory: DefaultReadService.Factory,
|
||||||
private val typingServiceFactory: DefaultTypingService.Factory,
|
private val typingServiceFactory: DefaultTypingService.Factory,
|
||||||
private val aliasServiceFactory: DefaultAliasService.Factory,
|
private val aliasServiceFactory: DefaultAliasService.Factory,
|
||||||
private val tagsServiceFactory: DefaultTagsService.Factory,
|
private val tagsServiceFactory: DefaultTagsService.Factory,
|
||||||
private val relationServiceFactory: DefaultRelationService.Factory,
|
private val relationServiceFactory: DefaultRelationService.Factory,
|
||||||
private val membershipServiceFactory: DefaultMembershipService.Factory,
|
private val roomCryptoServiceFactory: DefaultRoomCryptoService.Factory,
|
||||||
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory,
|
private val membershipServiceFactory: DefaultMembershipService.Factory,
|
||||||
private val roomVersionServiceFactory: DefaultRoomVersionService.Factory,
|
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory,
|
||||||
private val roomAccountDataServiceFactory: DefaultRoomAccountDataService.Factory,
|
private val roomVersionServiceFactory: DefaultRoomVersionService.Factory,
|
||||||
private val sendStateTask: SendStateTask,
|
private val roomAccountDataServiceFactory: DefaultRoomAccountDataService.Factory,
|
||||||
private val viaParameterFinder: ViaParameterFinder,
|
private val viaParameterFinder: ViaParameterFinder,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers) :
|
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||||
RoomFactory {
|
) : RoomFactory {
|
||||||
|
|
||||||
override fun create(roomId: String): Room {
|
override fun create(roomId: String): Room {
|
||||||
return DefaultRoom(
|
return DefaultRoom(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
roomSummaryDataSource = roomSummaryDataSource,
|
roomSummaryDataSource = roomSummaryDataSource,
|
||||||
|
roomCryptoService = roomCryptoServiceFactory.create(roomId),
|
||||||
timelineService = timelineServiceFactory.create(roomId),
|
timelineService = timelineServiceFactory.create(roomId),
|
||||||
threadsService = threadsServiceFactory.create(roomId),
|
threadsService = threadsServiceFactory.create(roomId),
|
||||||
threadsLocalService = threadsLocalServiceFactory.create(roomId),
|
threadsLocalService = threadsLocalServiceFactory.create(roomId),
|
||||||
|
@ -90,13 +90,11 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService:
|
||||||
typingService = typingServiceFactory.create(roomId),
|
typingService = typingServiceFactory.create(roomId),
|
||||||
aliasService = aliasServiceFactory.create(roomId),
|
aliasService = aliasServiceFactory.create(roomId),
|
||||||
tagsService = tagsServiceFactory.create(roomId),
|
tagsService = tagsServiceFactory.create(roomId),
|
||||||
cryptoService = cryptoService,
|
|
||||||
relationService = relationServiceFactory.create(roomId),
|
relationService = relationServiceFactory.create(roomId),
|
||||||
roomMembersService = membershipServiceFactory.create(roomId),
|
roomMembersService = membershipServiceFactory.create(roomId),
|
||||||
roomPushRuleService = roomPushRuleServiceFactory.create(roomId),
|
roomPushRuleService = roomPushRuleServiceFactory.create(roomId),
|
||||||
roomAccountDataService = roomAccountDataServiceFactory.create(roomId),
|
roomAccountDataService = roomAccountDataServiceFactory.create(roomId),
|
||||||
roomVersionService = roomVersionServiceFactory.create(roomId),
|
roomVersionService = roomVersionServiceFactory.create(roomId),
|
||||||
sendStateTask = sendStateTask,
|
|
||||||
viaParameterFinder = viaParameterFinder,
|
viaParameterFinder = viaParameterFinder,
|
||||||
coroutineDispatchers = coroutineDispatchers
|
coroutineDispatchers = coroutineDispatchers
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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 org.matrix.android.sdk.internal.session.room.crypto
|
||||||
|
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
|
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
||||||
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
|
import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
||||||
|
import java.security.InvalidParameterException
|
||||||
|
|
||||||
|
internal class DefaultRoomCryptoService @AssistedInject constructor(
|
||||||
|
@Assisted private val roomId: String,
|
||||||
|
private val cryptoService: CryptoService,
|
||||||
|
private val sendStateTask: SendStateTask,
|
||||||
|
) : RoomCryptoService {
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory {
|
||||||
|
fun create(roomId: String): DefaultRoomCryptoService
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEncrypted(): Boolean {
|
||||||
|
return cryptoService.isRoomEncrypted(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun encryptionAlgorithm(): String? {
|
||||||
|
return cryptoService.getEncryptionAlgorithm(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldEncryptForInvitedMembers(): Boolean {
|
||||||
|
return cryptoService.shouldEncryptForInvitedMembers(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun prepareToEncrypt() {
|
||||||
|
awaitCallback<Unit> {
|
||||||
|
cryptoService.prepareToEncrypt(roomId, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun enableEncryption(algorithm: String, force: Boolean) {
|
||||||
|
when {
|
||||||
|
(!force && isEncrypted() && encryptionAlgorithm() == MXCRYPTO_ALGORITHM_MEGOLM) -> {
|
||||||
|
throw IllegalStateException("Encryption is already enabled for this room")
|
||||||
|
}
|
||||||
|
(!force && algorithm != MXCRYPTO_ALGORITHM_MEGOLM) -> {
|
||||||
|
throw InvalidParameterException("Only MXCRYPTO_ALGORITHM_MEGOLM algorithm is supported")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val params = SendStateTask.Params(
|
||||||
|
roomId = roomId,
|
||||||
|
stateKey = "",
|
||||||
|
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
||||||
|
body = mapOf(
|
||||||
|
"algorithm" to algorithm
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
sendStateTask.execute(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,7 +60,7 @@ internal class DefaultSpace(
|
||||||
}
|
}
|
||||||
?: viaParameterFinder.computeViaParams(roomId, 3))
|
?: viaParameterFinder.computeViaParams(roomId, 3))
|
||||||
|
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_CHILD,
|
eventType = EventType.STATE_SPACE_CHILD,
|
||||||
stateKey = roomId,
|
stateKey = roomId,
|
||||||
body = SpaceChildContent(
|
body = SpaceChildContent(
|
||||||
|
@ -79,7 +79,7 @@ internal class DefaultSpace(
|
||||||
// return
|
// return
|
||||||
|
|
||||||
// edit state event and set via to null
|
// edit state event and set via to null
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_CHILD,
|
eventType = EventType.STATE_SPACE_CHILD,
|
||||||
stateKey = roomId,
|
stateKey = roomId,
|
||||||
body = SpaceChildContent(
|
body = SpaceChildContent(
|
||||||
|
@ -91,19 +91,19 @@ internal class DefaultSpace(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChildInfo(roomId: String): SpaceChildContent? {
|
override fun getChildInfo(roomId: String): SpaceChildContent? {
|
||||||
return room.getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
return room.stateService().getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.content.toModel<SpaceChildContent>()
|
?.content.toModel<SpaceChildContent>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setChildrenOrder(roomId: String, order: String?) {
|
override suspend fun setChildrenOrder(roomId: String, order: String?) {
|
||||||
val existing = room.getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
val existing = room.stateService().getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.content.toModel<SpaceChildContent>()
|
?.content.toModel<SpaceChildContent>()
|
||||||
?: throw IllegalArgumentException("$roomId is not a child of this space")
|
?: throw IllegalArgumentException("$roomId is not a child of this space")
|
||||||
|
|
||||||
// edit state event and set via to null
|
// edit state event and set via to null
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_CHILD,
|
eventType = EventType.STATE_SPACE_CHILD,
|
||||||
stateKey = roomId,
|
stateKey = roomId,
|
||||||
body = SpaceChildContent(
|
body = SpaceChildContent(
|
||||||
|
@ -140,7 +140,7 @@ internal class DefaultSpace(
|
||||||
// }
|
// }
|
||||||
|
|
||||||
override suspend fun setChildrenSuggested(roomId: String, suggested: Boolean) {
|
override suspend fun setChildrenSuggested(roomId: String, suggested: Boolean) {
|
||||||
val existing = room.getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
val existing = room.stateService().getStateEvents(setOf(EventType.STATE_SPACE_CHILD), QueryStringValue.Equals(roomId))
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.content.toModel<SpaceChildContent>()
|
?.content.toModel<SpaceChildContent>()
|
||||||
?: throw IllegalArgumentException("$roomId is not a child of this space")
|
?: throw IllegalArgumentException("$roomId is not a child of this space")
|
||||||
|
@ -150,7 +150,7 @@ internal class DefaultSpace(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// edit state event and set via to null
|
// edit state event and set via to null
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_CHILD,
|
eventType = EventType.STATE_SPACE_CHILD,
|
||||||
stateKey = roomId,
|
stateKey = roomId,
|
||||||
body = SpaceChildContent(
|
body = SpaceChildContent(
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
|
@ -258,7 +259,7 @@ internal class DefaultSpaceService @Inject constructor(
|
||||||
val room = roomGetter.getRoom(childRoomId)
|
val room = roomGetter.getRoom(childRoomId)
|
||||||
?: throw IllegalArgumentException("Unknown Room $childRoomId")
|
?: throw IllegalArgumentException("Unknown Room $childRoomId")
|
||||||
|
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_PARENT,
|
eventType = EventType.STATE_SPACE_PARENT,
|
||||||
stateKey = parentSpaceId,
|
stateKey = parentSpaceId,
|
||||||
body = SpaceParentContent(
|
body = SpaceParentContent(
|
||||||
|
@ -276,7 +277,7 @@ internal class DefaultSpaceService @Inject constructor(
|
||||||
if (existingEvent != null) {
|
if (existingEvent != null) {
|
||||||
// Should i check if it was sent by me?
|
// Should i check if it was sent by me?
|
||||||
// we don't check power level, it will throw if you cannot do that
|
// we don't check power level, it will throw if you cannot do that
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_SPACE_PARENT,
|
eventType = EventType.STATE_SPACE_PARENT,
|
||||||
stateKey = parentSpaceId,
|
stateKey = parentSpaceId,
|
||||||
body = SpaceParentContent(
|
body = SpaceParentContent(
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.matrix.android.sdk.MatrixTest
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
|
||||||
|
@ -148,14 +149,22 @@ class PushRulesConditionTest : MatrixTest {
|
||||||
val room2JoinedId = "2joined"
|
val room2JoinedId = "2joined"
|
||||||
val room3JoinedId = "3joined"
|
val room3JoinedId = "3joined"
|
||||||
|
|
||||||
val roomStub2Joined = mockk<Room> {
|
val roomMembershipService2 = mockk<MembershipService> {
|
||||||
every { getNumberOfJoinedMembers() } returns 2
|
every { getNumberOfJoinedMembers() } returns 2
|
||||||
}
|
}
|
||||||
|
|
||||||
val roomStub3Joined = mockk<Room> {
|
val roomMembershipService3 = mockk<MembershipService> {
|
||||||
every { getNumberOfJoinedMembers() } returns 3
|
every { getNumberOfJoinedMembers() } returns 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val roomStub2Joined = mockk<Room> {
|
||||||
|
every { membershipService() } returns roomMembershipService2
|
||||||
|
}
|
||||||
|
|
||||||
|
val roomStub3Joined = mockk<Room> {
|
||||||
|
every { membershipService() } returns roomMembershipService3
|
||||||
|
}
|
||||||
|
|
||||||
val roomGetterStub = mockk<RoomGetter> {
|
val roomGetterStub = mockk<RoomGetter> {
|
||||||
every { getRoom(room2JoinedId) } returns roomStub2Joined
|
every { getRoom(room2JoinedId) } returns roomStub2Joined
|
||||||
every { getRoom(room3JoinedId) } returns roomStub3Joined
|
every { getRoom(room3JoinedId) } returns roomStub3Joined
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ class AppStateHandler @Inject constructor(
|
||||||
if (spaceId != null) {
|
if (spaceId != null) {
|
||||||
uSession.coroutineScope.launch(Dispatchers.IO) {
|
uSession.coroutineScope.launch(Dispatchers.IO) {
|
||||||
tryOrNull {
|
tryOrNull {
|
||||||
uSession.getRoom(spaceId)?.loadRoomMembersIfNeeded()
|
uSession.getRoom(spaceId)?.membershipService()?.loadRoomMembersIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,8 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createMemberItems(queryParams: RoomMemberQueryParams) =
|
private fun createMemberItems(queryParams: RoomMemberQueryParams) =
|
||||||
room.getRoomMembers(queryParams)
|
room.membershipService()
|
||||||
|
.getRoomMembers(queryParams)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.sortedBy { it.displayName }
|
.sortedBy { it.displayName }
|
||||||
.disambiguate()
|
.disambiguate()
|
||||||
|
|
|
@ -30,7 +30,7 @@ class CallUserMapper(private val session: Session, private val protocolsChecker:
|
||||||
fun nativeRoomForVirtualRoom(roomId: String): String? {
|
fun nativeRoomForVirtualRoom(roomId: String): String? {
|
||||||
if (!protocolsChecker.supportVirtualRooms) return null
|
if (!protocolsChecker.supportVirtualRooms) return null
|
||||||
val virtualRoom = session.getRoom(roomId) ?: return null
|
val virtualRoom = session.getRoom(roomId) ?: return null
|
||||||
val virtualRoomEvent = virtualRoom.getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM)
|
val virtualRoomEvent = virtualRoom.roomAccountDataService().getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM)
|
||||||
return virtualRoomEvent?.content?.toModel<RoomVirtualContent>()?.nativeRoomId
|
return virtualRoomEvent?.content?.toModel<RoomVirtualContent>()?.nativeRoomId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class CallUserMapper(private val session: Session, private val protocolsChecker:
|
||||||
|
|
||||||
private suspend fun Room.markVirtual(nativeRoomId: String) {
|
private suspend fun Room.markVirtual(nativeRoomId: String) {
|
||||||
val virtualRoomContent = RoomVirtualContent(nativeRoomId = nativeRoomId)
|
val virtualRoomContent = RoomVirtualContent(nativeRoomId = nativeRoomId)
|
||||||
updateAccountData(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM, virtualRoomContent.toContent())
|
roomAccountDataService().updateAccountData(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM, virtualRoomContent.toContent())
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ensureVirtualRoomExists(userId: String, nativeRoomId: String): String {
|
private suspend fun ensureVirtualRoomExists(userId: String, nativeRoomId: String): String {
|
||||||
|
|
|
@ -30,7 +30,7 @@ fun WebRtcCall.getOpponentAsMatrixItem(session: Session): MatrixItem? {
|
||||||
roomSummary.toMatrixItem()
|
roomSummary.toMatrixItem()
|
||||||
} else {
|
} else {
|
||||||
val userId = roomSummary.otherMemberIds.first()
|
val userId = roomSummary.otherMemberIds.first()
|
||||||
return room.getRoomMember(userId)?.toMatrixItem()
|
return room.membershipService().getRoomMember(userId)?.toMatrixItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,11 +174,10 @@ class RoomDevToolViewModel @AssistedInject constructor(
|
||||||
val json = adapter.fromJson(state.editedContent ?: "")
|
val json = adapter.fromJson(state.editedContent ?: "")
|
||||||
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content))
|
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content))
|
||||||
|
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
state.selectedEvent?.type.orEmpty(),
|
state.selectedEvent?.type.orEmpty(),
|
||||||
state.selectedEvent?.stateKey.orEmpty(),
|
state.selectedEvent?.stateKey.orEmpty(),
|
||||||
json
|
json
|
||||||
|
|
||||||
)
|
)
|
||||||
_viewEvents.post(DevToolsViewEvents.ShowSnackMessage(stringProvider.getString(R.string.dev_tools_success_state_event)))
|
_viewEvents.post(DevToolsViewEvents.ShowSnackMessage(stringProvider.getString(R.string.dev_tools_success_state_event)))
|
||||||
setState {
|
setState {
|
||||||
|
@ -212,7 +211,7 @@ class RoomDevToolViewModel @AssistedInject constructor(
|
||||||
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_message_type))
|
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_message_type))
|
||||||
|
|
||||||
if (isState) {
|
if (isState) {
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType,
|
eventType,
|
||||||
state.sendEventDraft.stateKey.orEmpty(),
|
state.sendEventDraft.stateKey.orEmpty(),
|
||||||
json
|
json
|
||||||
|
@ -222,7 +221,7 @@ class RoomDevToolViewModel @AssistedInject constructor(
|
||||||
// val validParse = MoshiProvider.providesMoshi().adapter(MessageContent::class.java).fromJson(it.sendEventDraft.content ?: "")
|
// val validParse = MoshiProvider.providesMoshi().adapter(MessageContent::class.java).fromJson(it.sendEventDraft.content ?: "")
|
||||||
json.toModel<MessageContent>(catchError = false)
|
json.toModel<MessageContent>(catchError = false)
|
||||||
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_malformed_event))
|
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_malformed_event))
|
||||||
room.sendEvent(
|
room.sendService().sendEvent(
|
||||||
eventType,
|
eventType,
|
||||||
json
|
json
|
||||||
)
|
)
|
||||||
|
|
|
@ -89,6 +89,8 @@ import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.file.FileService
|
import org.matrix.android.sdk.api.session.file.FileService
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
|
@ -183,7 +185,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
setupPreviewUrlObservers()
|
setupPreviewUrlObservers()
|
||||||
room.getRoomSummaryLive()
|
room.getRoomSummaryLive()
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
tryOrNull { room.markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT) }
|
tryOrNull { room.readService().markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT) }
|
||||||
}
|
}
|
||||||
// Inform the SDK that the room is displayed
|
// Inform the SDK that the room is displayed
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
@ -194,7 +196,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
chatEffectManager.delegate = this
|
chatEffectManager.delegate = this
|
||||||
|
|
||||||
// Ensure to share the outbound session keys with all members
|
// Ensure to share the outbound session keys with all members
|
||||||
if (OutboundSessionKeySharingStrategy.WhenEnteringRoom == BuildConfig.outboundSessionKeySharingStrategy && room.isEncrypted()) {
|
if (OutboundSessionKeySharingStrategy.WhenEnteringRoom == BuildConfig.outboundSessionKeySharingStrategy && room.roomCryptoService().isEncrypted()) {
|
||||||
prepareForEncryption()
|
prepareForEncryption()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +252,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
prepareToEncrypt = Loading()
|
prepareToEncrypt = Loading()
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching {
|
runCatching {
|
||||||
room.prepareToEncrypt()
|
room.roomCryptoService().prepareToEncrypt()
|
||||||
}.fold({
|
}.fold({
|
||||||
prepareToEncrypt = Success(Unit)
|
prepareToEncrypt = Success(Unit)
|
||||||
}, {
|
}, {
|
||||||
|
@ -354,7 +356,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
private fun markThreadTimelineAsReadLocal() {
|
private fun markThreadTimelineAsReadLocal() {
|
||||||
initialState.rootThreadEventId?.let {
|
initialState.rootThreadEventId?.let {
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
room.markThreadAsRead(it)
|
room.threadsLocalService().markThreadAsRead(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,7 +492,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
private fun handleSetNewAvatar(action: RoomDetailAction.SetAvatarAction) {
|
private fun handleSetNewAvatar(action: RoomDetailAction.SetAvatarAction) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
room.updateAvatar(action.newAvatarUri, action.newAvatarFileName)
|
room.stateService().updateAvatar(action.newAvatarUri, action.newAvatarFileName)
|
||||||
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ActionFailure(action, failure))
|
_viewEvents.post(RoomDetailViewEvents.ActionFailure(action, failure))
|
||||||
|
@ -507,7 +509,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleJumpToReadReceipt(action: RoomDetailAction.JumpToReadReceipt) {
|
private fun handleJumpToReadReceipt(action: RoomDetailAction.JumpToReadReceipt) {
|
||||||
room.getUserReadReceipt(action.userId)
|
room.readService().getUserReadReceipt(action.userId)
|
||||||
?.let { handleNavigateToEvent(RoomDetailAction.NavigateToEvent(it, true)) }
|
?.let { handleNavigateToEvent(RoomDetailAction.NavigateToEvent(it, true)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +521,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
eventId = it))
|
eventId = it))
|
||||||
} ?: action.stickerContent
|
} ?: action.stickerContent
|
||||||
|
|
||||||
room.sendEvent(EventType.STICKER, content.toContent())
|
room.sendService().sendEvent(EventType.STICKER, content.toContent())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleStartCall(action: RoomDetailAction.StartCall) {
|
private fun handleStartCall(action: RoomDetailAction.StartCall) {
|
||||||
|
@ -639,7 +641,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
if (trackUnreadMessages.getAndSet(false)) {
|
if (trackUnreadMessages.getAndSet(false)) {
|
||||||
mostRecentDisplayedEvent?.root?.eventId?.also {
|
mostRecentDisplayedEvent?.root?.eventId?.also {
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
tryOrNull { room.setReadMarker(it) }
|
tryOrNull { room.readService().setReadMarker(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mostRecentDisplayedEvent = null
|
mostRecentDisplayedEvent = null
|
||||||
|
@ -652,12 +654,12 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMember(userId: String): RoomMemberSummary? {
|
fun getMember(userId: String): RoomMemberSummary? {
|
||||||
return room.getRoomMember(userId)
|
return room.membershipService().getRoomMember(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleComposerFocusChange(action: RoomDetailAction.ComposerFocusChange) {
|
private fun handleComposerFocusChange(action: RoomDetailAction.ComposerFocusChange) {
|
||||||
// Ensure outbound session keys
|
// Ensure outbound session keys
|
||||||
if (OutboundSessionKeySharingStrategy.WhenTyping == BuildConfig.outboundSessionKeySharingStrategy && room.isEncrypted()) {
|
if (OutboundSessionKeySharingStrategy.WhenTyping == BuildConfig.outboundSessionKeySharingStrategy && room.roomCryptoService().isEncrypted()) {
|
||||||
if (action.focused) {
|
if (action.focused) {
|
||||||
// Should we add some rate limit here, or do it only once per model lifecycle?
|
// Should we add some rate limit here, or do it only once per model lifecycle?
|
||||||
prepareForEncryption()
|
prepareForEncryption()
|
||||||
|
@ -738,36 +740,36 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
// PRIVATE METHODS *****************************************************************************
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
|
||||||
private fun handleSendReaction(action: RoomDetailAction.SendReaction) {
|
private fun handleSendReaction(action: RoomDetailAction.SendReaction) {
|
||||||
room.sendReaction(action.targetEventId, action.reaction)
|
room.relationService().sendReaction(action.targetEventId, action.reaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRedactEvent(action: RoomDetailAction.RedactAction) {
|
private fun handleRedactEvent(action: RoomDetailAction.RedactAction) {
|
||||||
val event = room.getTimelineEvent(action.targetEventId) ?: return
|
val event = room.getTimelineEvent(action.targetEventId) ?: return
|
||||||
room.redactEvent(event.root, action.reason)
|
room.sendService().redactEvent(event.root, action.reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUndoReact(action: RoomDetailAction.UndoReaction) {
|
private fun handleUndoReact(action: RoomDetailAction.UndoReaction) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
tryOrNull {
|
tryOrNull {
|
||||||
room.undoReaction(action.targetEventId, action.reaction)
|
room.relationService().undoReaction(action.targetEventId, action.reaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUpdateQuickReaction(action: RoomDetailAction.UpdateQuickReactAction) {
|
private fun handleUpdateQuickReaction(action: RoomDetailAction.UpdateQuickReactAction) {
|
||||||
if (action.add) {
|
if (action.add) {
|
||||||
room.sendReaction(action.targetEventId, action.selectedReaction)
|
room.relationService().sendReaction(action.targetEventId, action.selectedReaction)
|
||||||
} else {
|
} else {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
tryOrNull {
|
tryOrNull {
|
||||||
room.undoReaction(action.targetEventId, action.selectedReaction)
|
room.relationService().undoReaction(action.targetEventId, action.selectedReaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSendMedia(action: RoomDetailAction.SendMedia) {
|
private fun handleSendMedia(action: RoomDetailAction.SendMedia) {
|
||||||
room.sendMedias(
|
room.sendService().sendMedias(
|
||||||
action.attachments,
|
action.attachments,
|
||||||
action.compressBeforeSending,
|
action.compressBeforeSending,
|
||||||
emptySet(),
|
emptySet(),
|
||||||
|
@ -902,8 +904,8 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
it.root.isTextMessage() -> room.resendTextMessage(it)
|
it.root.isTextMessage() -> room.sendService().resendTextMessage(it)
|
||||||
it.root.isAttachmentMessage() -> room.resendMediaMessage(it)
|
it.root.isAttachmentMessage() -> room.sendService().resendMediaMessage(it)
|
||||||
else -> {
|
else -> {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -919,13 +921,13 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
room.deleteFailedEcho(it)
|
room.sendService().deleteFailedEcho(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCancel(action: RoomDetailAction.CancelSend) {
|
private fun handleCancel(action: RoomDetailAction.CancelSend) {
|
||||||
if (action.force) {
|
if (action.force) {
|
||||||
room.cancelSend(action.eventId)
|
room.sendService().cancelSend(action.eventId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val targetEventId = action.eventId
|
val targetEventId = action.eventId
|
||||||
|
@ -935,16 +937,16 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
Timber.e("Cannot cancel message, it is not sending")
|
Timber.e("Cannot cancel message, it is not sending")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
room.cancelSend(targetEventId)
|
room.sendService().cancelSend(targetEventId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleResendAll() {
|
private fun handleResendAll() {
|
||||||
room.resendAllFailedMessages()
|
room.sendService().resendAllFailedMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRemoveAllFailedMessages() {
|
private fun handleRemoveAllFailedMessages() {
|
||||||
room.cancelAllFailedMessages()
|
room.sendService().cancelAllFailedMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeEventDisplayedActions() {
|
private fun observeEventDisplayedActions() {
|
||||||
|
@ -967,7 +969,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
bufferedMostRecentDisplayedEvent.root.eventId?.let { eventId ->
|
bufferedMostRecentDisplayedEvent.root.eventId?.let { eventId ->
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
tryOrNull { room.setReadReceipt(eventId) }
|
tryOrNull { room.readService().setReadReceipt(eventId) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -984,14 +986,14 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
private fun handleMarkAllAsRead() {
|
private fun handleMarkAllAsRead() {
|
||||||
setState { copy(unreadState = UnreadState.HasNoUnread) }
|
setState { copy(unreadState = UnreadState.HasNoUnread) }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
tryOrNull { room.markAsRead(ReadService.MarkAsReadParams.BOTH) }
|
tryOrNull { room.readService().markAsRead(ReadService.MarkAsReadParams.BOTH) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleReportContent(action: RoomDetailAction.ReportContent) {
|
private fun handleReportContent(action: RoomDetailAction.ReportContent) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val event = try {
|
val event = try {
|
||||||
room.reportContent(action.eventId, -100, action.reason)
|
room.reportingService().reportContent(action.eventId, -100, action.reason)
|
||||||
RoomDetailViewEvents.ActionSuccess(action)
|
RoomDetailViewEvents.ActionSuccess(action)
|
||||||
} catch (failure: Exception) {
|
} catch (failure: Exception) {
|
||||||
RoomDetailViewEvents.ActionFailure(action, failure)
|
RoomDetailViewEvents.ActionFailure(action, failure)
|
||||||
|
@ -1081,13 +1083,13 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
room.getTimelineEvent(action.eventId)?.let { pollTimelineEvent ->
|
room.getTimelineEvent(action.eventId)?.let { pollTimelineEvent ->
|
||||||
val currentVote = pollTimelineEvent.annotations?.pollResponseSummary?.aggregatedContent?.myVote
|
val currentVote = pollTimelineEvent.annotations?.pollResponseSummary?.aggregatedContent?.myVote
|
||||||
if (currentVote != action.optionKey) {
|
if (currentVote != action.optionKey) {
|
||||||
room.voteToPoll(action.eventId, action.optionKey)
|
room.sendService().voteToPoll(action.eventId, action.optionKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEndPoll(eventId: String) {
|
private fun handleEndPoll(eventId: String) {
|
||||||
room.endPoll(eventId)
|
room.sendService().endPoll(eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeSyncState() {
|
private fun observeSyncState() {
|
||||||
|
@ -1265,7 +1267,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
timeline.removeAllListeners()
|
timeline.removeAllListeners()
|
||||||
decryptionFailureTracker.onTimeLineDisposed(room.roomId)
|
decryptionFailureTracker.onTimeLineDisposed(room.roomId)
|
||||||
if (vectorPreferences.sendTypingNotifs()) {
|
if (vectorPreferences.sendTypingNotifs()) {
|
||||||
room.userStopsTyping()
|
room.typingService().userStopsTyping()
|
||||||
}
|
}
|
||||||
chatEffectManager.delegate = null
|
chatEffectManager.delegate = null
|
||||||
chatEffectManager.dispose()
|
chatEffectManager.dispose()
|
||||||
|
|
|
@ -53,6 +53,8 @@ import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
|
import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm
|
import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm
|
||||||
|
@ -205,12 +207,12 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
is ParsedCommand.ErrorNotACommand -> {
|
is ParsedCommand.ErrorNotACommand -> {
|
||||||
// Send the text message to the room
|
// Send the text message to the room
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = action.text,
|
replyInThreadText = action.text,
|
||||||
autoMarkdown = action.autoMarkdown)
|
autoMarkdown = action.autoMarkdown)
|
||||||
} else {
|
} else {
|
||||||
room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown)
|
room.sendService().sendTextMessage(action.text, autoMarkdown = action.autoMarkdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
_viewEvents.post(MessageComposerViewEvents.MessageSent)
|
_viewEvents.post(MessageComposerViewEvents.MessageSent)
|
||||||
|
@ -231,12 +233,12 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
is ParsedCommand.SendPlainText -> {
|
is ParsedCommand.SendPlainText -> {
|
||||||
// Send the text message to the room, without markdown
|
// Send the text message to the room, without markdown
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = parsedCommand.message,
|
replyInThreadText = parsedCommand.message,
|
||||||
autoMarkdown = false)
|
autoMarkdown = false)
|
||||||
} else {
|
} else {
|
||||||
room.sendTextMessage(parsedCommand.message, autoMarkdown = false)
|
room.sendService().sendTextMessage(parsedCommand.message, autoMarkdown = false)
|
||||||
}
|
}
|
||||||
_viewEvents.post(MessageComposerViewEvents.MessageSent)
|
_viewEvents.post(MessageComposerViewEvents.MessageSent)
|
||||||
popDraft()
|
popDraft()
|
||||||
|
@ -286,13 +288,16 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
is ParsedCommand.SendEmote -> {
|
is ParsedCommand.SendEmote -> {
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = parsedCommand.message,
|
replyInThreadText = parsedCommand.message,
|
||||||
msgType = MessageType.MSGTYPE_EMOTE,
|
msgType = MessageType.MSGTYPE_EMOTE,
|
||||||
autoMarkdown = action.autoMarkdown)
|
autoMarkdown = action.autoMarkdown)
|
||||||
} else {
|
} else {
|
||||||
room.sendTextMessage(parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown)
|
room.sendService().sendTextMessage(
|
||||||
|
text = parsedCommand.message,
|
||||||
|
msgType = MessageType.MSGTYPE_EMOTE,
|
||||||
|
autoMarkdown = action.autoMarkdown)
|
||||||
}
|
}
|
||||||
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
||||||
popDraft()
|
popDraft()
|
||||||
|
@ -300,12 +305,12 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
is ParsedCommand.SendRainbow -> {
|
is ParsedCommand.SendRainbow -> {
|
||||||
val message = parsedCommand.message.toString()
|
val message = parsedCommand.message.toString()
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = parsedCommand.message,
|
replyInThreadText = parsedCommand.message,
|
||||||
formattedText = rainbowGenerator.generate(message))
|
formattedText = rainbowGenerator.generate(message))
|
||||||
} else {
|
} else {
|
||||||
room.sendFormattedTextMessage(message, rainbowGenerator.generate(message))
|
room.sendService().sendFormattedTextMessage(message, rainbowGenerator.generate(message))
|
||||||
}
|
}
|
||||||
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
||||||
popDraft()
|
popDraft()
|
||||||
|
@ -313,13 +318,13 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
is ParsedCommand.SendRainbowEmote -> {
|
is ParsedCommand.SendRainbowEmote -> {
|
||||||
val message = parsedCommand.message.toString()
|
val message = parsedCommand.message.toString()
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = parsedCommand.message,
|
replyInThreadText = parsedCommand.message,
|
||||||
msgType = MessageType.MSGTYPE_EMOTE,
|
msgType = MessageType.MSGTYPE_EMOTE,
|
||||||
formattedText = rainbowGenerator.generate(message))
|
formattedText = rainbowGenerator.generate(message))
|
||||||
} else {
|
} else {
|
||||||
room.sendFormattedTextMessage(message, rainbowGenerator.generate(message), MessageType.MSGTYPE_EMOTE)
|
room.sendService().sendFormattedTextMessage(message, rainbowGenerator.generate(message), MessageType.MSGTYPE_EMOTE)
|
||||||
}
|
}
|
||||||
|
|
||||||
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
||||||
|
@ -329,12 +334,12 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
val text = "[${stringProvider.getString(R.string.spoiler)}](${parsedCommand.message})"
|
val text = "[${stringProvider.getString(R.string.spoiler)}](${parsedCommand.message})"
|
||||||
val formattedText = "<span data-mx-spoiler>${parsedCommand.message}</span>"
|
val formattedText = "<span data-mx-spoiler>${parsedCommand.message}</span>"
|
||||||
if (state.rootThreadEventId != null) {
|
if (state.rootThreadEventId != null) {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = state.rootThreadEventId,
|
rootThreadEventId = state.rootThreadEventId,
|
||||||
replyInThreadText = text,
|
replyInThreadText = text,
|
||||||
formattedText = formattedText)
|
formattedText = formattedText)
|
||||||
} else {
|
} else {
|
||||||
room.sendFormattedTextMessage(
|
room.sendService().sendFormattedTextMessage(
|
||||||
text,
|
text,
|
||||||
formattedText)
|
formattedText)
|
||||||
}
|
}
|
||||||
|
@ -377,7 +382,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
popDraft()
|
popDraft()
|
||||||
}
|
}
|
||||||
is ParsedCommand.DiscardSession -> {
|
is ParsedCommand.DiscardSession -> {
|
||||||
if (room.isEncrypted()) {
|
if (room.roomCryptoService().isEncrypted()) {
|
||||||
session.cryptoService().discardOutboundSession(room.roomId)
|
session.cryptoService().discardOutboundSession(room.roomId)
|
||||||
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand))
|
||||||
popDraft()
|
popDraft()
|
||||||
|
@ -489,13 +494,13 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
if (inReplyTo != null) {
|
if (inReplyTo != null) {
|
||||||
// TODO check if same content?
|
// TODO check if same content?
|
||||||
room.getTimelineEvent(inReplyTo)?.let {
|
room.getTimelineEvent(inReplyTo)?.let {
|
||||||
room.editReply(state.sendMode.timelineEvent, it, action.text.toString())
|
room.relationService().editReply(state.sendMode.timelineEvent, it, action.text.toString())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val messageContent = state.sendMode.timelineEvent.getLastMessageContent()
|
val messageContent = state.sendMode.timelineEvent.getLastMessageContent()
|
||||||
val existingBody = messageContent?.body ?: ""
|
val existingBody = messageContent?.body ?: ""
|
||||||
if (existingBody != action.text) {
|
if (existingBody != action.text) {
|
||||||
room.editTextMessage(state.sendMode.timelineEvent,
|
room.relationService().editTextMessage(state.sendMode.timelineEvent,
|
||||||
messageContent?.msgType ?: MessageType.MSGTYPE_TEXT,
|
messageContent?.msgType ?: MessageType.MSGTYPE_TEXT,
|
||||||
action.text,
|
action.text,
|
||||||
action.autoMarkdown)
|
action.autoMarkdown)
|
||||||
|
@ -507,7 +512,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
popDraft()
|
popDraft()
|
||||||
}
|
}
|
||||||
is SendMode.Quote -> {
|
is SendMode.Quote -> {
|
||||||
room.sendQuotedTextMessage(
|
room.sendService().sendQuotedTextMessage(
|
||||||
quotedEvent = state.sendMode.timelineEvent,
|
quotedEvent = state.sendMode.timelineEvent,
|
||||||
text = action.text.toString(),
|
text = action.text.toString(),
|
||||||
autoMarkdown = action.autoMarkdown,
|
autoMarkdown = action.autoMarkdown,
|
||||||
|
@ -521,12 +526,12 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
// If threads are disabled this will make the fallback replies visible to clients with threads enabled
|
// If threads are disabled this will make the fallback replies visible to clients with threads enabled
|
||||||
val rootThreadEventId = if (showInThread) timelineEvent.root.getRootThreadEventId() else null
|
val rootThreadEventId = if (showInThread) timelineEvent.root.getRootThreadEventId() else null
|
||||||
state.rootThreadEventId?.let {
|
state.rootThreadEventId?.let {
|
||||||
room.replyInThread(
|
room.relationService().replyInThread(
|
||||||
rootThreadEventId = it,
|
rootThreadEventId = it,
|
||||||
replyInThreadText = action.text.toString(),
|
replyInThreadText = action.text.toString(),
|
||||||
autoMarkdown = action.autoMarkdown,
|
autoMarkdown = action.autoMarkdown,
|
||||||
eventReplied = timelineEvent)
|
eventReplied = timelineEvent)
|
||||||
} ?: room.replyToMessage(
|
} ?: room.relationService().replyToMessage(
|
||||||
eventReplied = timelineEvent,
|
eventReplied = timelineEvent,
|
||||||
replyText = action.text.toString(),
|
replyText = action.text.toString(),
|
||||||
autoMarkdown = action.autoMarkdown,
|
autoMarkdown = action.autoMarkdown,
|
||||||
|
@ -552,13 +557,13 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
// Otherwise we clear the composer and remove the draft from db
|
// Otherwise we clear the composer and remove the draft from db
|
||||||
setState { copy(sendMode = SendMode.Regular("", false)) }
|
setState { copy(sendMode = SendMode.Regular("", false)) }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
room.deleteDraft()
|
room.draftService().deleteDraft()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadDraftIfAny() {
|
private fun loadDraftIfAny() {
|
||||||
val currentDraft = room.getDraft()
|
val currentDraft = room.draftService().getDraft()
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
// Create a sendMode from a draft and retrieve the TimelineEvent
|
// Create a sendMode from a draft and retrieve the TimelineEvent
|
||||||
|
@ -589,9 +594,9 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
private fun handleUserIsTyping(action: MessageComposerAction.UserIsTyping) {
|
private fun handleUserIsTyping(action: MessageComposerAction.UserIsTyping) {
|
||||||
if (vectorPreferences.sendTypingNotifs()) {
|
if (vectorPreferences.sendTypingNotifs()) {
|
||||||
if (action.isTyping) {
|
if (action.isTyping) {
|
||||||
room.userIsTyping()
|
room.typingService().userIsTyping()
|
||||||
} else {
|
} else {
|
||||||
room.userStopsTyping()
|
room.typingService().userStopsTyping()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -603,9 +608,9 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
ChatEffect.CONFETTI -> R.string.default_message_emote_confetti
|
ChatEffect.CONFETTI -> R.string.default_message_emote_confetti
|
||||||
ChatEffect.SNOWFALL -> R.string.default_message_emote_snow
|
ChatEffect.SNOWFALL -> R.string.default_message_emote_snow
|
||||||
})
|
})
|
||||||
room.sendTextMessage(defaultMessage, MessageType.MSGTYPE_EMOTE)
|
room.sendService().sendTextMessage(defaultMessage, MessageType.MSGTYPE_EMOTE)
|
||||||
} else {
|
} else {
|
||||||
room.sendTextMessage(sendChatEffect.message, sendChatEffect.chatEffect.toMessageType())
|
room.sendService().sendTextMessage(sendChatEffect.message, sendChatEffect.chatEffect.toMessageType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,19 +653,19 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) {
|
private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) {
|
||||||
launchSlashCommandFlowSuspendable(changeTopic) {
|
launchSlashCommandFlowSuspendable(changeTopic) {
|
||||||
room.updateTopic(changeTopic.topic)
|
room.stateService().updateTopic(changeTopic.topic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) {
|
private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) {
|
||||||
launchSlashCommandFlowSuspendable(invite) {
|
launchSlashCommandFlowSuspendable(invite) {
|
||||||
room.invite(invite.userId, invite.reason)
|
room.membershipService().invite(invite.userId, invite.reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) {
|
private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) {
|
||||||
launchSlashCommandFlowSuspendable(invite) {
|
launchSlashCommandFlowSuspendable(invite) {
|
||||||
room.invite3pid(invite.threePid)
|
room.membershipService().invite3pid(invite.threePid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,7 +678,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
launchSlashCommandFlowSuspendable(setUserPowerLevel) {
|
launchSlashCommandFlowSuspendable(setUserPowerLevel) {
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent)
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,25 +706,25 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) {
|
private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) {
|
||||||
launchSlashCommandFlowSuspendable(removeUser) {
|
launchSlashCommandFlowSuspendable(removeUser) {
|
||||||
room.remove(removeUser.userId, removeUser.reason)
|
room.membershipService().remove(removeUser.userId, removeUser.reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) {
|
private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) {
|
||||||
launchSlashCommandFlowSuspendable(ban) {
|
launchSlashCommandFlowSuspendable(ban) {
|
||||||
room.ban(ban.userId, ban.reason)
|
room.membershipService().ban(ban.userId, ban.reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) {
|
private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) {
|
||||||
launchSlashCommandFlowSuspendable(unban) {
|
launchSlashCommandFlowSuspendable(unban) {
|
||||||
room.unban(unban.userId, unban.reason)
|
room.membershipService().unban(unban.userId, unban.reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) {
|
private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) {
|
||||||
launchSlashCommandFlowSuspendable(changeRoomName) {
|
launchSlashCommandFlowSuspendable(changeRoomName) {
|
||||||
room.updateName(changeRoomName.name)
|
room.stateService().updateName(changeRoomName.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,14 +740,14 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
?.copy(displayName = changeDisplayName.displayName)
|
?.copy(displayName = changeDisplayName.displayName)
|
||||||
?.toContent()
|
?.toContent()
|
||||||
?.let {
|
?.let {
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it)
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) {
|
private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) {
|
||||||
launchSlashCommandFlowSuspendable(changeAvatar) {
|
launchSlashCommandFlowSuspendable(changeAvatar) {
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_AVATAR, stateKey = "", RoomAvatarContent(changeAvatar.url).toContent())
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_AVATAR, stateKey = "", RoomAvatarContent(changeAvatar.url).toContent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,7 +757,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
?.copy(avatarUrl = changeAvatar.url)
|
?.copy(avatarUrl = changeAvatar.url)
|
||||||
?.toContent()
|
?.toContent()
|
||||||
?.let {
|
?.let {
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it)
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,8 +798,8 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootThreadEventId?.let {
|
rootThreadEventId?.let {
|
||||||
room.replyInThread(it, sequence)
|
room.relationService().replyInThread(it, sequence)
|
||||||
} ?: room.sendTextMessage(sequence)
|
} ?: room.sendService().sendTextMessage(sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -805,19 +810,19 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
when {
|
when {
|
||||||
it.sendMode is SendMode.Regular && !it.sendMode.fromSharing -> {
|
it.sendMode is SendMode.Regular && !it.sendMode.fromSharing -> {
|
||||||
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
||||||
room.saveDraft(UserDraft.Regular(draft))
|
room.draftService().saveDraft(UserDraft.Regular(draft))
|
||||||
}
|
}
|
||||||
it.sendMode is SendMode.Reply -> {
|
it.sendMode is SendMode.Reply -> {
|
||||||
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
||||||
room.saveDraft(UserDraft.Reply(it.sendMode.timelineEvent.root.eventId!!, draft))
|
room.draftService().saveDraft(UserDraft.Reply(it.sendMode.timelineEvent.root.eventId!!, draft))
|
||||||
}
|
}
|
||||||
it.sendMode is SendMode.Quote -> {
|
it.sendMode is SendMode.Quote -> {
|
||||||
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
||||||
room.saveDraft(UserDraft.Quote(it.sendMode.timelineEvent.root.eventId!!, draft))
|
room.draftService().saveDraft(UserDraft.Quote(it.sendMode.timelineEvent.root.eventId!!, draft))
|
||||||
}
|
}
|
||||||
it.sendMode is SendMode.Edit -> {
|
it.sendMode is SendMode.Edit -> {
|
||||||
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
setState { copy(sendMode = it.sendMode.copy(text = draft)) }
|
||||||
room.saveDraft(UserDraft.Edit(it.sendMode.timelineEvent.root.eventId!!, draft))
|
room.draftService().saveDraft(UserDraft.Edit(it.sendMode.timelineEvent.root.eventId!!, draft))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -838,7 +843,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
} else {
|
} else {
|
||||||
audioMessageHelper.stopRecording(convertForSending = true)?.let { audioType ->
|
audioMessageHelper.stopRecording(convertForSending = true)?.let { audioType ->
|
||||||
if (audioType.duration > 1000) {
|
if (audioType.duration > 1000) {
|
||||||
room.sendMedia(
|
room.sendService().sendMedia(
|
||||||
attachment = audioType.toContentAttachmentData(isVoiceMessage = true),
|
attachment = audioType.toContentAttachmentData(isVoiceMessage = true),
|
||||||
compressBeforeSending = false,
|
compressBeforeSending = false,
|
||||||
roomIds = emptySet(),
|
roomIds = emptySet(),
|
||||||
|
@ -905,7 +910,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
playingAudioContent?.toContentAttachmentData()?.let { voiceDraft ->
|
playingAudioContent?.toContentAttachmentData()?.let { voiceDraft ->
|
||||||
val content = voiceDraft.toJsonString()
|
val content = voiceDraft.toJsonString()
|
||||||
room.saveDraft(UserDraft.Voice(content))
|
room.draftService().saveDraft(UserDraft.Voice(content))
|
||||||
setState { copy(sendMode = SendMode.Voice(content)) }
|
setState { copy(sendMode = SendMode.Voice(content)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ class ViewEditHistoryViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val data = try {
|
val data = try {
|
||||||
room.fetchEditHistory(eventId)
|
room.relationService().fetchEditHistory(eventId)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
setState {
|
setState {
|
||||||
copy(editList = Fail(failure))
|
copy(editList = Fail(failure))
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
|
import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
||||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||||
|
|
|
@ -45,18 +45,18 @@ class TimelineFactory @Inject constructor(private val session: Session, private
|
||||||
val settings = timelineSettingsFactory.create(rootThreadEventId)
|
val settings = timelineSettingsFactory.create(rootThreadEventId)
|
||||||
|
|
||||||
if (!session.vectorCallService.protocolChecker.supportVirtualRooms) {
|
if (!session.vectorCallService.protocolChecker.supportVirtualRooms) {
|
||||||
return mainRoom.createTimeline(eventId, settings)
|
return mainRoom.timelineService().createTimeline(eventId, settings)
|
||||||
}
|
}
|
||||||
val virtualRoomId = session.vectorCallService.userMapper.virtualRoomForNativeRoom(mainRoom.roomId)
|
val virtualRoomId = session.vectorCallService.userMapper.virtualRoomForNativeRoom(mainRoom.roomId)
|
||||||
return if (virtualRoomId == null) {
|
return if (virtualRoomId == null) {
|
||||||
mainRoom.createTimeline(eventId, settings)
|
mainRoom.timelineService().createTimeline(eventId, settings)
|
||||||
} else {
|
} else {
|
||||||
val virtualRoom = session.getRoom(virtualRoomId)!!
|
val virtualRoom = session.getRoom(virtualRoomId)!!
|
||||||
MergedTimelines(
|
MergedTimelines(
|
||||||
coroutineScope = coroutineScope,
|
coroutineScope = coroutineScope,
|
||||||
mainTimeline = mainRoom.createTimeline(eventId, settings),
|
mainTimeline = mainRoom.timelineService().createTimeline(eventId, settings),
|
||||||
secondaryTimelineParams = MergedTimelines.SecondaryTimelineParams(
|
secondaryTimelineParams = MergedTimelines.SecondaryTimelineParams(
|
||||||
timeline = virtualRoom.createTimeline(null, settings),
|
timeline = virtualRoom.timelineService().createTimeline(null, settings),
|
||||||
shouldFilterTypes = true,
|
shouldFilterTypes = true,
|
||||||
allowedTypes = secondaryTimelineAllowedTypes
|
allowedTypes = secondaryTimelineAllowedTypes
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationCancelContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationCancelContent
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
@ -34,6 +34,7 @@ import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFrag
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import org.matrix.android.sdk.flow.unwrap
|
import org.matrix.android.sdk.flow.unwrap
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class MigrateRoomViewModel @AssistedInject constructor(
|
||||||
val summary = session.getRoomSummary(initialState.roomId)
|
val summary = session.getRoomSummary(initialState.roomId)
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
currentVersion = room?.getRoomVersion(),
|
currentVersion = room?.roomVersionService()?.getRoomVersion(),
|
||||||
isPublic = summary?.isPublic ?: false,
|
isPublic = summary?.isPublic ?: false,
|
||||||
otherMemberCount = summary?.otherMemberIds?.count() ?: 0,
|
otherMemberCount = summary?.otherMemberIds?.count() ?: 0,
|
||||||
knownParents = summary?.flattenParentIds ?: emptyList()
|
knownParents = summary?.flattenParentIds ?: emptyList()
|
||||||
|
|
|
@ -50,12 +50,12 @@ class UpgradeRoomViewModelTask @Inject constructor(
|
||||||
|
|
||||||
val room = session.getRoom(params.roomId)
|
val room = session.getRoom(params.roomId)
|
||||||
?: return Result.UnknownRoom
|
?: return Result.UnknownRoom
|
||||||
if (!room.userMayUpgradeRoom(session.myUserId)) {
|
if (!room.roomVersionService().userMayUpgradeRoom(session.myUserId)) {
|
||||||
return Result.NotAllowed
|
return Result.NotAllowed
|
||||||
}
|
}
|
||||||
|
|
||||||
val updatedRoomId = try {
|
val updatedRoomId = try {
|
||||||
room.upgradeToVersion(params.newVersion)
|
room.roomVersionService().upgradeToVersion(params.newVersion)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
return Result.ErrorFailure(failure)
|
return Result.ErrorFailure(failure)
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class UpgradeRoomViewModelTask @Inject constructor(
|
||||||
params.userIdsToAutoInvite.forEach {
|
params.userIdsToAutoInvite.forEach {
|
||||||
params.progressReporter?.invoke(false, currentStep, totalStep)
|
params.progressReporter?.invoke(false, currentStep, totalStep)
|
||||||
tryOrNull {
|
tryOrNull {
|
||||||
session.getRoom(updatedRoomId)?.invite(it)
|
session.getRoom(updatedRoomId)?.membershipService()?.invite(it)
|
||||||
}
|
}
|
||||||
currentStep++
|
currentStep++
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPublicRoom(roomId: String): Boolean {
|
fun isPublicRoom(roomId: String): Boolean {
|
||||||
return session.getRoom(roomId)?.isPublic().orFalse()
|
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRIVATE METHODS *****************************************************************************
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
@ -254,7 +254,7 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
room.setRoomNotificationState(action.notificationState)
|
room.roomPushRuleService().setRoomNotificationState(action.notificationState)
|
||||||
} catch (failure: Exception) {
|
} catch (failure: Exception) {
|
||||||
_viewEvents.post(RoomListViewEvents.Failure(failure))
|
_viewEvents.post(RoomListViewEvents.Failure(failure))
|
||||||
}
|
}
|
||||||
|
@ -299,13 +299,13 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
action.tag.otherTag()
|
action.tag.otherTag()
|
||||||
?.takeIf { room.roomSummary()?.hasTag(it).orFalse() }
|
?.takeIf { room.roomSummary()?.hasTag(it).orFalse() }
|
||||||
?.let { tagToRemove ->
|
?.let { tagToRemove ->
|
||||||
room.deleteTag(tagToRemove)
|
room.tagsService().deleteTag(tagToRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the tag. We do not handle the order for the moment
|
// Set the tag. We do not handle the order for the moment
|
||||||
room.addTag(action.tag, 0.5)
|
room.tagsService().addTag(action.tag, 0.5)
|
||||||
} else {
|
} else {
|
||||||
room.deleteTag(action.tag)
|
room.tagsService().deleteTag(action.tag)
|
||||||
}
|
}
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomListViewEvents.Failure(failure))
|
_viewEvents.post(RoomListViewEvents.Failure(failure))
|
||||||
|
|
|
@ -85,7 +85,7 @@ class ThreadListViewModel @AssistedInject constructor(@Assisted val initialState
|
||||||
private fun observeThreadSummaries() {
|
private fun observeThreadSummaries() {
|
||||||
room?.flow()
|
room?.flow()
|
||||||
?.liveThreadSummaries()
|
?.liveThreadSummaries()
|
||||||
?.map { room.enhanceThreadWithEditions(it) }
|
?.map { room.threadsService().enhanceThreadWithEditions(it) }
|
||||||
?.flowOn(room.coroutineDispatchers.io)
|
?.flowOn(room.coroutineDispatchers.io)
|
||||||
?.execute { asyncThreads ->
|
?.execute { asyncThreads ->
|
||||||
copy(threadSummaryList = asyncThreads)
|
copy(threadSummaryList = asyncThreads)
|
||||||
|
@ -99,10 +99,10 @@ class ThreadListViewModel @AssistedInject constructor(@Assisted val initialState
|
||||||
private fun observeThreadsList() {
|
private fun observeThreadsList() {
|
||||||
room?.flow()
|
room?.flow()
|
||||||
?.liveThreadList()
|
?.liveThreadList()
|
||||||
?.map { room.mapEventsWithEdition(it) }
|
?.map { room.threadsLocalService().mapEventsWithEdition(it) }
|
||||||
?.map {
|
?.map {
|
||||||
it.map { threadRootEvent ->
|
it.map { threadRootEvent ->
|
||||||
val isParticipating = room.isUserParticipatingInThread(threadRootEvent.eventId)
|
val isParticipating = room.threadsLocalService().isUserParticipatingInThread(threadRootEvent.eventId)
|
||||||
ThreadTimelineEvent(threadRootEvent, isParticipating)
|
ThreadTimelineEvent(threadRootEvent, isParticipating)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ class ThreadListViewModel @AssistedInject constructor(@Assisted val initialState
|
||||||
private fun fetchThreadList() {
|
private fun fetchThreadList() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
room?.fetchThreadSummaries()
|
room?.threadsService()?.fetchThreadSummaries()
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,8 @@ class InviteUsersToRoomViewModel @AssistedInject constructor(
|
||||||
selections.asFlow()
|
selections.asFlow()
|
||||||
.map { user ->
|
.map { user ->
|
||||||
when (user) {
|
when (user) {
|
||||||
is PendingSelection.UserPendingSelection -> room.invite(user.user.userId, null)
|
is PendingSelection.UserPendingSelection -> room.membershipService().invite(user.user.userId, null)
|
||||||
is PendingSelection.ThreePidPendingSelection -> room.invite3pid(user.threePid)
|
is PendingSelection.ThreePidPendingSelection -> room.membershipService().invite3pid(user.threePid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.catch { cause ->
|
.catch { cause ->
|
||||||
|
|
|
@ -105,6 +105,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||||
val stateKey = session.myUserId
|
val stateKey = session.myUserId
|
||||||
session
|
session
|
||||||
.getRoom(roomArgs.roomId)
|
.getRoom(roomArgs.roomId)
|
||||||
|
?.stateService()
|
||||||
?.sendStateEvent(
|
?.sendStateEvent(
|
||||||
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
||||||
stateKey = stateKey,
|
stateKey = stateKey,
|
||||||
|
@ -147,7 +148,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||||
.getSafeActiveSession()
|
.getSafeActiveSession()
|
||||||
?.let { session ->
|
?.let { session ->
|
||||||
session.coroutineScope.launch(session.coroutineDispatchers.io) {
|
session.coroutineScope.launch(session.coroutineDispatchers.io) {
|
||||||
session.getRoom(roomId)?.stopLiveLocation(session.myUserId)
|
session.getRoom(roomId)?.stateService()?.stopLiveLocation(session.myUserId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,10 +175,11 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
room
|
room
|
||||||
|
.stateService()
|
||||||
.getLiveLocationBeaconInfo(userId, true)
|
.getLiveLocationBeaconInfo(userId, true)
|
||||||
?.eventId
|
?.eventId
|
||||||
?.let {
|
?.let {
|
||||||
room.sendLiveLocation(
|
room.sendService().sendLiveLocation(
|
||||||
beaconInfoEventId = it,
|
beaconInfoEventId = it,
|
||||||
latitude = locationData.latitude,
|
latitude = locationData.latitude,
|
||||||
longitude = locationData.longitude,
|
longitude = locationData.longitude,
|
||||||
|
|
|
@ -136,7 +136,7 @@ class LocationSharingViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun shareLocation(locationData: LocationData?, isUserLocation: Boolean) {
|
private fun shareLocation(locationData: LocationData?, isUserLocation: Boolean) {
|
||||||
locationData?.let { location ->
|
locationData?.let { location ->
|
||||||
room.sendLocation(
|
room.sendService().sendLocation(
|
||||||
latitude = location.latitude,
|
latitude = location.latitude,
|
||||||
longitude = location.longitude,
|
longitude = location.longitude,
|
||||||
uncertainty = location.uncertainty,
|
uncertainty = location.uncertainty,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.file.FileService
|
import org.matrix.android.sdk.api.session.file.FileService
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.util.MimeTypes
|
import org.matrix.android.sdk.api.util.MimeTypes
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
|
@ -135,7 +135,7 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt
|
||||||
initialIndex = inMemoryData.indexOfFirst { it.eventId == args.eventId }.coerceAtLeast(0)
|
initialIndex = inMemoryData.indexOfFirst { it.eventId == args.eventId }.coerceAtLeast(0)
|
||||||
dataSourceFactory.createProvider(inMemoryData, room, lifecycleScope)
|
dataSourceFactory.createProvider(inMemoryData, room, lifecycleScope)
|
||||||
} else {
|
} else {
|
||||||
val events = room?.getAttachmentMessages().orEmpty()
|
val events = room?.timelineService()?.getAttachmentMessages().orEmpty()
|
||||||
initialIndex = events.indexOfFirst { it.eventId == args.eventId }.coerceAtLeast(0)
|
initialIndex = events.indexOfFirst { it.eventId == args.eventId }.coerceAtLeast(0)
|
||||||
dataSourceFactory.createProvider(events, lifecycleScope)
|
dataSourceFactory.createProvider(events, lifecycleScope)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.getUser
|
import org.matrix.android.sdk.api.session.getUser
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent
|
||||||
|
|
|
@ -106,7 +106,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||||
val room = session.getRoom(roomId)
|
val room = session.getRoom(roomId)
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
tryOrNull { room.markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT) }
|
tryOrNull { room.readService().markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendMatrixEvent(message: String, session: Session, room: Room, context: Context?) {
|
private fun sendMatrixEvent(message: String, session: Session, room: Room, context: Context?) {
|
||||||
room.sendTextMessage(message)
|
room.sendService().sendTextMessage(message)
|
||||||
|
|
||||||
// Create a new event to be displayed in the notification drawer, right now
|
// Create a new event to be displayed in the notification drawer, right now
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class OutdatedEventDetector @Inject constructor(
|
||||||
val eventID = notifiableEvent.eventId
|
val eventID = notifiableEvent.eventId
|
||||||
val roomID = notifiableEvent.roomId
|
val roomID = notifiableEvent.roomId
|
||||||
val room = session.getRoom(roomID) ?: return false
|
val room = session.getRoom(roomID) ?: return false
|
||||||
return room.isEventRead(eventID)
|
return room.readService().isEventRead(eventID)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
|
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
|
||||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||||
|
|
|
@ -26,6 +26,7 @@ import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.poll.PollMode
|
import im.vector.app.features.poll.PollMode
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.PollType
|
import org.matrix.android.sdk.api.session.room.model.message.PollType
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||||
|
@ -109,7 +110,7 @@ class CreatePollViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
when (state.mode) {
|
when (state.mode) {
|
||||||
PollMode.CREATE -> room.sendPoll(state.pollType, state.question, nonEmptyOptions)
|
PollMode.CREATE -> room.sendService().sendPoll(state.pollType, state.question, nonEmptyOptions)
|
||||||
PollMode.EDIT -> sendEditedPoll(state.editedEventId!!, state.pollType, state.question, nonEmptyOptions)
|
PollMode.EDIT -> sendEditedPoll(state.editedEventId!!, state.pollType, state.question, nonEmptyOptions)
|
||||||
}
|
}
|
||||||
_viewEvents.post(CreatePollViewEvents.Success)
|
_viewEvents.post(CreatePollViewEvents.Success)
|
||||||
|
@ -119,7 +120,7 @@ class CreatePollViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun sendEditedPoll(editedEventId: String, pollType: PollType, question: String, options: List<String>) {
|
private fun sendEditedPoll(editedEventId: String, pollType: PollType, question: String, options: List<String>) {
|
||||||
val editedEvent = room.getTimelineEvent(editedEventId) ?: return
|
val editedEvent = room.getTimelineEvent(editedEventId) ?: return
|
||||||
room.editPoll(editedEvent, pollType, question, options)
|
room.relationService().editPoll(editedEvent, pollType, question, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleOnAddOption() {
|
private fun handleOnAddOption() {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
|
@ -93,7 +94,7 @@ class RequireActiveMembershipViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
val senderId = room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId))?.senderId
|
val senderId = room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId))?.senderId
|
||||||
val senderDisplayName = senderId?.takeIf { it != session.myUserId }?.let {
|
val senderDisplayName = senderId?.takeIf { it != session.myUserId }?.let {
|
||||||
room.getRoomMember(it)?.displayName ?: it
|
room.membershipService().getRoomMember(it)?.displayName ?: it
|
||||||
}
|
}
|
||||||
val viewEvent = when (roomSummary.membership) {
|
val viewEvent = when (roomSummary.membership) {
|
||||||
Membership.LEAVE -> {
|
Membership.LEAVE -> {
|
||||||
|
|
|
@ -87,8 +87,8 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
isMine = session.myUserId == this.userId,
|
isMine = session.myUserId == this.userId,
|
||||||
userMatrixItem = room?.getRoomMember(initialState.userId)?.toMatrixItem()?.let { Success(it) } ?: Uninitialized,
|
userMatrixItem = room?.membershipService()?.getRoomMember(initialState.userId)?.toMatrixItem()?.let { Success(it) } ?: Uninitialized,
|
||||||
hasReadReceipt = room?.getUserReadReceipt(initialState.userId) != null,
|
hasReadReceipt = room?.readService()?.getUserReadReceipt(initialState.userId) != null,
|
||||||
isSpace = room?.roomSummary()?.roomType == RoomType.SPACE
|
isSpace = room?.roomSummary()?.roomType == RoomType.SPACE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch(Dispatchers.Main) {
|
viewModelScope.launch(Dispatchers.Main) {
|
||||||
// Do we have a room member for this id.
|
// Do we have a room member for this id.
|
||||||
val roomMember = withContext(Dispatchers.Default) {
|
val roomMember = withContext(Dispatchers.Default) {
|
||||||
room?.getRoomMember(initialState.userId)
|
room?.membershipService()?.getRoomMember(initialState.userId)
|
||||||
}
|
}
|
||||||
// If not, we look for profile info on the server
|
// If not, we look for profile info on the server
|
||||||
if (room == null || roomMember == null) {
|
if (room == null || roomMember == null) {
|
||||||
|
@ -228,7 +228,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
||||||
try {
|
try {
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent)
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent)
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.OnSetPowerLevelSuccess)
|
_viewEvents.post(RoomMemberProfileViewEvents.OnSetPowerLevelSuccess)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
||||||
|
@ -257,7 +257,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
||||||
room.invite(initialState.userId)
|
room.membershipService().invite(initialState.userId)
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.OnInviteActionSuccess)
|
_viewEvents.post(RoomMemberProfileViewEvents.OnInviteActionSuccess)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
||||||
|
@ -272,7 +272,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
||||||
room.remove(initialState.userId, action.reason)
|
room.membershipService().remove(initialState.userId, action.reason)
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.OnKickActionSuccess)
|
_viewEvents.post(RoomMemberProfileViewEvents.OnKickActionSuccess)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomMemberProfileViewEvents.Failure(failure))
|
||||||
|
@ -289,9 +289,9 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
||||||
try {
|
try {
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
||||||
if (membership == Membership.BAN) {
|
if (membership == Membership.BAN) {
|
||||||
room.unban(initialState.userId, action.reason)
|
room.membershipService().unban(initialState.userId, action.reason)
|
||||||
} else {
|
} else {
|
||||||
room.ban(initialState.userId, action.reason)
|
room.membershipService().ban(initialState.userId, action.reason)
|
||||||
}
|
}
|
||||||
_viewEvents.post(RoomMemberProfileViewEvents.OnBanActionSuccess)
|
_viewEvents.post(RoomMemberProfileViewEvents.OnBanActionSuccess)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
||||||
|
@ -97,9 +98,9 @@ class RoomProfileViewModel @AssistedInject constructor(
|
||||||
copy(
|
copy(
|
||||||
roomCreateContent = async,
|
roomCreateContent = async,
|
||||||
// This is a shortcut, we should do the next lines elsewhere, but keep it like that for the moment.
|
// This is a shortcut, we should do the next lines elsewhere, but keep it like that for the moment.
|
||||||
recommendedRoomVersion = room.getRecommendedVersion(),
|
recommendedRoomVersion = room.roomVersionService().getRecommendedVersion(),
|
||||||
isUsingUnstableRoomVersion = room.isUsingUnstableRoomVersion(),
|
isUsingUnstableRoomVersion = room.roomVersionService().isUsingUnstableRoomVersion(),
|
||||||
canUpgradeRoom = room.userMayUpgradeRoom(session.myUserId),
|
canUpgradeRoom = room.roomVersionService().userMayUpgradeRoom(session.myUserId),
|
||||||
isTombstoned = room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE) != null
|
isTombstoned = room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE) != null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -144,14 +145,14 @@ class RoomProfileViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPublicRoom(): Boolean {
|
fun isPublicRoom(): Boolean {
|
||||||
return room.isPublic()
|
return room.stateService().isPublic()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEnableEncryption() {
|
private fun handleEnableEncryption() {
|
||||||
postLoading(true)
|
postLoading(true)
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val result = runCatching { room.enableEncryption() }
|
val result = runCatching { room.roomCryptoService().enableEncryption() }
|
||||||
postLoading(false)
|
postLoading(false)
|
||||||
result.onFailure { failure ->
|
result.onFailure { failure ->
|
||||||
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
||||||
|
@ -178,7 +179,7 @@ class RoomProfileViewModel @AssistedInject constructor(
|
||||||
private fun handleChangeNotificationMode(action: RoomProfileAction.ChangeRoomNotificationState) {
|
private fun handleChangeNotificationMode(action: RoomProfileAction.ChangeRoomNotificationState) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
room.setRoomNotificationState(action.notificationState)
|
room.roomPushRuleService().setRoomNotificationState(action.notificationState)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
||||||
}
|
}
|
||||||
|
@ -213,7 +214,7 @@ class RoomProfileViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(RoomProfileViewEvents.Loading())
|
_viewEvents.post(RoomProfileViewEvents.Loading())
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
try {
|
try {
|
||||||
room.enableEncryption(force = true)
|
room.roomCryptoService().enableEncryption(force = true)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.e(failure, "Failed to restore encryption state in room ${room.roomId}")
|
Timber.e(failure, "Failed to restore encryption state in room ${room.roomId}")
|
||||||
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
||||||
|
|
|
@ -109,7 +109,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching { room.getRoomAliases() }
|
runCatching { room.aliasService().getRoomAliases() }
|
||||||
.fold(
|
.fold(
|
||||||
{
|
{
|
||||||
setState { copy(localAliases = Success(it.sorted())) }
|
setState { copy(localAliases = Success(it.sorted())) }
|
||||||
|
@ -304,7 +304,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
|
||||||
postLoading(true)
|
postLoading(true)
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
room.updateCanonicalAlias(canonicalAlias, alternativeAliases)
|
room.stateService().updateCanonicalAlias(canonicalAlias, alternativeAliases)
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
|
@ -328,7 +328,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching { room.addAlias(previousState.value) }
|
runCatching { room.aliasService().addAlias(previousState.value) }
|
||||||
.onFailure {
|
.onFailure {
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
|
@ -115,7 +116,7 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia
|
||||||
}
|
}
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
room.unban(roomMemberSummary.userId, null)
|
room.membershipService().unban(roomMemberSummary.userId, null)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
_viewEvents.post(RoomBannedMemberListViewEvents.ToastError(stringProvider.getString(R.string.failed_to_unban)))
|
_viewEvents.post(RoomBannedMemberListViewEvents.ToastError(stringProvider.getString(R.string.failed_to_unban)))
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -92,7 +92,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||||
copy(roomMemberSummaries = async)
|
copy(roomMemberSummaries = async)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (room.isEncrypted()) {
|
if (room.roomCryptoService().isEncrypted()) {
|
||||||
room.flow().liveRoomMembers(roomMemberQueryParams)
|
room.flow().liveRoomMembers(roomMemberQueryParams)
|
||||||
.flatMapLatest { membersSummary ->
|
.flatMapLatest { membersSummary ->
|
||||||
session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
||||||
|
@ -197,7 +197,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||||
|
|
||||||
private fun handleRevokeThreePidInvite(action: RoomMemberListAction.RevokeThreePidInvite) {
|
private fun handleRevokeThreePidInvite(action: RoomMemberListAction.RevokeThreePidInvite) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
eventType = EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
||||||
stateKey = action.stateKey,
|
stateKey = action.stateKey,
|
||||||
body = emptyMap()
|
body = emptyMap()
|
||||||
|
|
|
@ -74,7 +74,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor(
|
||||||
private fun handleSelectNotificationState(action: RoomNotificationSettingsAction.SelectNotificationState) {
|
private fun handleSelectNotificationState(action: RoomNotificationSettingsAction.SelectNotificationState) {
|
||||||
setState { copy(isLoading = true) }
|
setState { copy(isLoading = true) }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching { room.setRoomNotificationState(action.notificationState) }
|
runCatching { room.roomPushRuleService().setRoomNotificationState(action.notificationState) }
|
||||||
.fold(
|
.fold(
|
||||||
{
|
{
|
||||||
setState {
|
setState {
|
||||||
|
|
|
@ -124,7 +124,7 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent.toContent())
|
room.stateService().sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent.toContent())
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
|
|
@ -70,7 +70,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
|
|
||||||
val homeServerCapabilities = session.homeServerCapabilitiesService().getHomeServerCapabilities()
|
val homeServerCapabilities = session.homeServerCapabilitiesService().getHomeServerCapabilities()
|
||||||
val canUseRestricted = homeServerCapabilities
|
val canUseRestricted = homeServerCapabilities
|
||||||
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion())
|
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.roomVersionService().getRoomVersion())
|
||||||
|
|
||||||
val restrictedSupport = homeServerCapabilities.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
|
val restrictedSupport = homeServerCapabilities.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
|
||||||
val couldUpgradeToRestricted = restrictedSupport == HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED
|
val couldUpgradeToRestricted = restrictedSupport == HomeServerCapabilities.RoomCapabilitySupport.SUPPORTED
|
||||||
|
@ -249,25 +249,25 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
||||||
when (val avatarAction = state.avatarAction) {
|
when (val avatarAction = state.avatarAction) {
|
||||||
RoomSettingsViewState.AvatarAction.None -> Unit
|
RoomSettingsViewState.AvatarAction.None -> Unit
|
||||||
RoomSettingsViewState.AvatarAction.DeleteAvatar -> {
|
RoomSettingsViewState.AvatarAction.DeleteAvatar -> {
|
||||||
operationList.add { room.deleteAvatar() }
|
operationList.add { room.stateService().deleteAvatar() }
|
||||||
}
|
}
|
||||||
is RoomSettingsViewState.AvatarAction.UpdateAvatar -> {
|
is RoomSettingsViewState.AvatarAction.UpdateAvatar -> {
|
||||||
operationList.add { room.updateAvatar(avatarAction.newAvatarUri, avatarAction.newAvatarFileName) }
|
operationList.add { room.stateService().updateAvatar(avatarAction.newAvatarUri, avatarAction.newAvatarFileName) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (summary?.name != state.newName) {
|
if (summary?.name != state.newName) {
|
||||||
operationList.add { room.updateName(state.newName ?: "") }
|
operationList.add { room.stateService().updateName(state.newName ?: "") }
|
||||||
}
|
}
|
||||||
if (summary?.topic != state.newTopic) {
|
if (summary?.topic != state.newTopic) {
|
||||||
operationList.add { room.updateTopic(state.newTopic ?: "") }
|
operationList.add { room.stateService().updateTopic(state.newTopic ?: "") }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.newHistoryVisibility != null) {
|
if (state.newHistoryVisibility != null) {
|
||||||
operationList.add { room.updateHistoryReadability(state.newHistoryVisibility) }
|
operationList.add { room.stateService().updateHistoryReadability(state.newHistoryVisibility) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.newRoomJoinRules.hasChanged()) {
|
if (state.newRoomJoinRules.hasChanged()) {
|
||||||
operationList.add { room.updateJoinRule(state.newRoomJoinRules.newJoinRules, state.newRoomJoinRules.newGuestAccess) }
|
operationList.add { room.stateService().updateJoinRule(state.newRoomJoinRules.newJoinRules, state.newRoomJoinRules.newGuestAccess) }
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
updateLoadingState(isLoading = true)
|
updateLoadingState(isLoading = true)
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.getRoomSummary
|
import org.matrix.android.sdk.api.session.getRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
|
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
|
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
|
||||||
|
@ -103,7 +104,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
|
||||||
var safeRule: RoomJoinRules = joinRulesContent?.joinRules ?: RoomJoinRules.INVITE
|
var safeRule: RoomJoinRules = joinRulesContent?.joinRules ?: RoomJoinRules.INVITE
|
||||||
// server is not really checking that, just to be sure let's check
|
// server is not really checking that, just to be sure let's check
|
||||||
val restrictedSupportedByThisVersion = homeServerCapabilities
|
val restrictedSupportedByThisVersion = homeServerCapabilities
|
||||||
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion())
|
.isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.roomVersionService().getRoomVersion())
|
||||||
if (safeRule == RoomJoinRules.RESTRICTED &&
|
if (safeRule == RoomJoinRules.RESTRICTED &&
|
||||||
!restrictedSupportedByThisVersion) {
|
!restrictedSupportedByThisVersion) {
|
||||||
safeRule = RoomJoinRules.INVITE
|
safeRule = RoomJoinRules.INVITE
|
||||||
|
@ -191,9 +192,9 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
when (state.currentRoomJoinRules) {
|
when (state.currentRoomJoinRules) {
|
||||||
RoomJoinRules.PUBLIC -> room.setJoinRulePublic()
|
RoomJoinRules.PUBLIC -> room.stateService().setJoinRulePublic()
|
||||||
RoomJoinRules.INVITE -> room.setJoinRuleInviteOnly()
|
RoomJoinRules.INVITE -> room.stateService().setJoinRuleInviteOnly()
|
||||||
RoomJoinRules.RESTRICTED -> room.setJoinRuleRestricted(state.updatedAllowList.map { it.id })
|
RoomJoinRules.RESTRICTED -> room.stateService().setJoinRuleRestricted(state.updatedAllowList.map { it.id })
|
||||||
RoomJoinRules.KNOCK,
|
RoomJoinRules.KNOCK,
|
||||||
RoomJoinRules.PRIVATE,
|
RoomJoinRules.PRIVATE,
|
||||||
null -> {
|
null -> {
|
||||||
|
@ -294,7 +295,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
|
||||||
setState { copy(updatingStatus = Loading()) }
|
setState { copy(updatingStatus = Loading()) }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
room.setJoinRuleRestricted(candidates.map { it.id })
|
room.stateService().setJoinRuleRestricted(candidates.map { it.id })
|
||||||
setState { copy(updatingStatus = Success(Unit)) }
|
setState { copy(updatingStatus = Success(Unit)) }
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
setState { copy(updatingStatus = Fail(failure)) }
|
setState { copy(updatingStatus = Fail(failure)) }
|
||||||
|
|
|
@ -73,7 +73,7 @@ class RoomUploadsViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
val result = room.getUploads(20, token)
|
val result = room.uploadsService().getUploads(20, token)
|
||||||
|
|
||||||
token = result.nextToken
|
token = result.nextToken
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ class IncomingShareViewModel @AssistedInject constructor(
|
||||||
is SharedData.Text -> {
|
is SharedData.Text -> {
|
||||||
state.selectedRoomIds.forEach { roomId ->
|
state.selectedRoomIds.forEach { roomId ->
|
||||||
val room = session.getRoom(roomId)
|
val room = session.getRoom(roomId)
|
||||||
room?.sendTextMessage(sharedData.text)
|
room?.sendService()?.sendTextMessage(sharedData.text)
|
||||||
}
|
}
|
||||||
// This is it, pass the first roomId to let the screen open it
|
// This is it, pass the first roomId to let the screen open it
|
||||||
_viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(state.selectedRoomIds.first()))
|
_viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(state.selectedRoomIds.first()))
|
||||||
|
@ -153,6 +153,7 @@ class IncomingShareViewModel @AssistedInject constructor(
|
||||||
// Pick the first room to send the media
|
// Pick the first room to send the media
|
||||||
selectedRoomIds.firstOrNull()
|
selectedRoomIds.firstOrNull()
|
||||||
?.let { roomId -> session.getRoom(roomId) }
|
?.let { roomId -> session.getRoom(roomId) }
|
||||||
|
?.sendService()
|
||||||
?.sendMedias(grouped.notPreviewables, compressMediaBeforeSending, selectedRoomIds)
|
?.sendMedias(grouped.notPreviewables, compressMediaBeforeSending, selectedRoomIds)
|
||||||
|
|
||||||
// Ensure they will not be sent twice
|
// Ensure they will not be sent twice
|
||||||
|
@ -173,6 +174,7 @@ class IncomingShareViewModel @AssistedInject constructor(
|
||||||
// Pick the first room to send the media
|
// Pick the first room to send the media
|
||||||
selectedRoomIds.firstOrNull()
|
selectedRoomIds.firstOrNull()
|
||||||
?.let { roomId -> session.getRoom(roomId) }
|
?.let { roomId -> session.getRoom(roomId) }
|
||||||
|
?.sendService()
|
||||||
?.sendMedias(attachmentData, compressMediaBeforeSending, selectedRoomIds)
|
?.sendMedias(attachmentData, compressMediaBeforeSending, selectedRoomIds)
|
||||||
// This is it, pass the first roomId to let the screen open it
|
// This is it, pass the first roomId to let the screen open it
|
||||||
_viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(selectedRoomIds.first()))
|
_viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(selectedRoomIds.first()))
|
||||||
|
|
|
@ -212,7 +212,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa
|
||||||
}
|
}
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
orderCommands.forEach {
|
orderCommands.forEach {
|
||||||
session.getRoom(it.spaceId)?.updateAccountData(
|
session.getRoom(it.spaceId)?.roomAccountDataService()?.updateAccountData(
|
||||||
RoomAccountDataTypes.EVENT_TYPE_SPACE_ORDER,
|
RoomAccountDataTypes.EVENT_TYPE_SPACE_ORDER,
|
||||||
SpaceOrderContent(order = it.order).toContent()
|
SpaceOrderContent(order = it.order).toContent()
|
||||||
)
|
)
|
||||||
|
@ -292,6 +292,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa
|
||||||
val rootSpaces = async.invoke().orEmpty().filter { it.flattenParentIds.isEmpty() }
|
val rootSpaces = async.invoke().orEmpty().filter { it.flattenParentIds.isEmpty() }
|
||||||
val orders = rootSpaces.associate {
|
val orders = rootSpaces.associate {
|
||||||
it.roomId to session.getRoom(it.roomId)
|
it.roomId to session.getRoom(it.roomId)
|
||||||
|
?.roomAccountDataService()
|
||||||
?.getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_SPACE_ORDER)
|
?.getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_SPACE_ORDER)
|
||||||
?.content.toModel<SpaceOrderContent>()
|
?.content.toModel<SpaceOrderContent>()
|
||||||
?.safeOrder()
|
?.safeOrder()
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||||
|
@ -117,7 +118,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
}
|
}
|
||||||
val userId = eventData["user_id"] as String
|
val userId = eventData["user_id"] as String
|
||||||
Timber.d("Received request to get options for bot $userId in room $roomId requested")
|
Timber.d("Received request to get options for bot $userId in room $roomId requested")
|
||||||
val stateEvents = room.getStateEvents(setOf(EventType.BOT_OPTIONS))
|
val stateEvents = room.stateService().getStateEvents(setOf(EventType.BOT_OPTIONS))
|
||||||
var botOptionsEvent: Event? = null
|
var botOptionsEvent: Event? = null
|
||||||
val stateKey = "_$userId"
|
val stateKey = "_$userId"
|
||||||
for (stateEvent in stateEvents) {
|
for (stateEvent in stateEvents) {
|
||||||
|
@ -196,7 +197,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Timber.d("Received request join rules in room $roomId")
|
Timber.d("Received request join rules in room $roomId")
|
||||||
val joinedEvents = room.getStateEvents(setOf(EventType.STATE_ROOM_JOIN_RULES))
|
val joinedEvents = room.stateService().getStateEvents(setOf(EventType.STATE_ROOM_JOIN_RULES))
|
||||||
if (joinedEvents.isNotEmpty()) {
|
if (joinedEvents.isNotEmpty()) {
|
||||||
widgetPostAPIMediator.sendObjectResponse(Event::class.java, joinedEvents.last(), eventData)
|
widgetPostAPIMediator.sendObjectResponse(Event::class.java, joinedEvents.last(), eventData)
|
||||||
} else {
|
} else {
|
||||||
|
@ -316,7 +317,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
val params = HashMap<String, Any>()
|
val params = HashMap<String, Any>()
|
||||||
params["status"] = status
|
params["status"] = status
|
||||||
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.PLUMBING,
|
eventType = EventType.PLUMBING,
|
||||||
stateKey = "",
|
stateKey = "",
|
||||||
body = params
|
body = params
|
||||||
|
@ -341,7 +342,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
val stateKey = "_$userId"
|
val stateKey = "_$userId"
|
||||||
|
|
||||||
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
||||||
room.sendStateEvent(
|
room.stateService().sendStateEvent(
|
||||||
eventType = EventType.BOT_OPTIONS,
|
eventType = EventType.BOT_OPTIONS,
|
||||||
stateKey = stateKey,
|
stateKey = stateKey,
|
||||||
body = content
|
body = content
|
||||||
|
@ -383,12 +384,12 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
val userId = eventData["user_id"] as String
|
val userId = eventData["user_id"] as String
|
||||||
val description = "Received request to invite $userId into room $roomId"
|
val description = "Received request to invite $userId into room $roomId"
|
||||||
Timber.d(description)
|
Timber.d(description)
|
||||||
val member = room.getRoomMember(userId)
|
val member = room.membershipService().getRoomMember(userId)
|
||||||
if (member != null && member.membership == Membership.JOIN) {
|
if (member != null && member.membership == Membership.JOIN) {
|
||||||
widgetPostAPIMediator.sendSuccess(eventData)
|
widgetPostAPIMediator.sendSuccess(eventData)
|
||||||
} else {
|
} else {
|
||||||
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
|
||||||
room.invite(userId = userId)
|
room.membershipService().invite(userId = userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +403,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
||||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val numberOfJoinedMembers = room.getNumberOfJoinedMembers()
|
val numberOfJoinedMembers = room.membershipService().getNumberOfJoinedMembers()
|
||||||
widgetPostAPIMediator.sendIntegerResponse(numberOfJoinedMembers, eventData)
|
widgetPostAPIMediator.sendIntegerResponse(numberOfJoinedMembers, eventData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue