mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 01:55:04 +08:00
Merge branch 'develop' into feature/crypto
This commit is contained in:
commit
81330d30cf
@ -47,9 +47,7 @@ android {
|
||||
// Set to true to log privacy or sensible data, such as token
|
||||
// TODO Set to false
|
||||
buildConfigField "boolean", "LOG_PRIVATE_DATA", "false"
|
||||
|
||||
// Set to BODY instead of NONE to enable logging
|
||||
//TODO Revert BODY
|
||||
buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.HEADERS"
|
||||
}
|
||||
|
||||
@ -93,6 +91,7 @@ dependencies {
|
||||
def moshi_version = '1.8.0'
|
||||
def lifecycle_version = '2.0.0'
|
||||
def coroutines_version = "1.0.1"
|
||||
def markwon_version = '3.0.0'
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.aar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
@ -114,6 +113,8 @@ dependencies {
|
||||
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
|
||||
|
||||
implementation "ru.noties.markwon:core:$markwon_version"
|
||||
|
||||
// Database
|
||||
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
|
||||
kapt 'dk.ilios:realmfieldnameshelper:1.1.1'
|
||||
|
@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||
@ -78,7 +77,7 @@ object RoomDataHelper {
|
||||
fun fakeInitialSync(monarchy: Monarchy, roomId: String) {
|
||||
monarchy.runTransactionSync { realm ->
|
||||
val roomEntity = realm.createObject<RoomEntity>(roomId)
|
||||
roomEntity.membership = MyMembership.JOINED
|
||||
roomEntity.membership = Membership.JOIN
|
||||
val eventList = createFakeListOfEvents(10)
|
||||
val chunkEntity = realm.createObject<ChunkEntity>().apply {
|
||||
nextToken = null
|
||||
|
@ -20,7 +20,9 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.InstrumentedTest
|
||||
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.database.model.SessionRealmModule
|
||||
import im.vector.matrix.android.internal.session.room.EventRelationExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
|
||||
@ -46,7 +48,9 @@ internal class TimelineTest : InstrumentedTest {
|
||||
fun setup() {
|
||||
Timber.plant(Timber.DebugTree())
|
||||
Realm.init(context())
|
||||
val testConfiguration = RealmConfiguration.Builder().name("test-realm").build()
|
||||
val testConfiguration = RealmConfiguration.Builder().name("test-realm")
|
||||
.modules(SessionRealmModule()).build()
|
||||
|
||||
Realm.deleteRealm(testConfiguration)
|
||||
monarchy = Monarchy.Builder().setRealmConfiguration(testConfiguration).build()
|
||||
RoomDataHelper.fakeInitialSync(monarchy, ROOM_ID)
|
||||
@ -58,8 +62,16 @@ internal class TimelineTest : InstrumentedTest {
|
||||
val paginationTask = FakePaginationTask(tokenChunkEventPersistor)
|
||||
val getContextOfEventTask = FakeGetContextOfEventTask(tokenChunkEventPersistor)
|
||||
val roomMemberExtractor = SenderRoomMemberExtractor(ROOM_ID)
|
||||
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor)
|
||||
return DefaultTimeline(ROOM_ID, initialEventId, monarchy.realmConfiguration, taskExecutor, getContextOfEventTask, timelineEventFactory, paginationTask, null)
|
||||
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, EventRelationExtractor())
|
||||
return DefaultTimeline(
|
||||
ROOM_ID,
|
||||
initialEventId,
|
||||
monarchy.realmConfiguration,
|
||||
taskExecutor,
|
||||
getContextOfEventTask,
|
||||
timelineEventFactory,
|
||||
paginationTask,
|
||||
null)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.matrix.android.api
|
||||
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
@ -25,53 +24,53 @@ import java.util.regex.Pattern
|
||||
object MatrixPatterns {
|
||||
|
||||
// Note: TLD is not mandatory (localhost, IP address...)
|
||||
private val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?"
|
||||
private const val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?"
|
||||
|
||||
// regex pattern to find matrix user ids in a string.
|
||||
// See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
|
||||
private val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
|
||||
val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = Pattern.compile(MATRIX_USER_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
|
||||
private val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = Pattern.compile(MATRIX_USER_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find room ids in a string.
|
||||
private val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX"
|
||||
val PATTERN_CONTAIN_MATRIX_ROOM_IDENTIFIER = Pattern.compile(MATRIX_ROOM_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX"
|
||||
private val PATTERN_CONTAIN_MATRIX_ROOM_IDENTIFIER = Pattern.compile(MATRIX_ROOM_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find room aliases in a string.
|
||||
private val MATRIX_ROOM_ALIAS_REGEX = "#[A-Z0-9._%#@=+-]+$DOMAIN_REGEX"
|
||||
val PATTERN_CONTAIN_MATRIX_ALIAS = Pattern.compile(MATRIX_ROOM_ALIAS_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_ROOM_ALIAS_REGEX = "#[A-Z0-9._%#@=+-]+$DOMAIN_REGEX"
|
||||
private val PATTERN_CONTAIN_MATRIX_ALIAS = Pattern.compile(MATRIX_ROOM_ALIAS_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find message ids in a string.
|
||||
private val MATRIX_EVENT_IDENTIFIER_REGEX = "\\$[A-Z0-9]+$DOMAIN_REGEX"
|
||||
val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER = Pattern.compile(MATRIX_EVENT_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_EVENT_IDENTIFIER_REGEX = "\\$[A-Z0-9]+$DOMAIN_REGEX"
|
||||
private val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER = Pattern.compile(MATRIX_EVENT_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find message ids in a string.
|
||||
private val MATRIX_EVENT_IDENTIFIER_V3_REGEX = "\\$[A-Z0-9/+]+"
|
||||
val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 = Pattern.compile(MATRIX_EVENT_IDENTIFIER_V3_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_EVENT_IDENTIFIER_V3_REGEX = "\\$[A-Z0-9/+]+"
|
||||
private val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 = Pattern.compile(MATRIX_EVENT_IDENTIFIER_V3_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find group ids in a string.
|
||||
private val MATRIX_GROUP_IDENTIFIER_REGEX = "\\+[A-Z0-9=_\\-./]+$DOMAIN_REGEX"
|
||||
val PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER = Pattern.compile(MATRIX_GROUP_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
private const val MATRIX_GROUP_IDENTIFIER_REGEX = "\\+[A-Z0-9=_\\-./]+$DOMAIN_REGEX"
|
||||
private val PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER = Pattern.compile(MATRIX_GROUP_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// regex pattern to find permalink with message id.
|
||||
// Android does not support in URL so extract it.
|
||||
private val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/"
|
||||
private val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/"
|
||||
val SEP_REGEX = "/"
|
||||
private const val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/"
|
||||
private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/"
|
||||
const val SEP_REGEX = "/"
|
||||
|
||||
private val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
private const val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
private val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
private const val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
private val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_APP_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
private const val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_APP_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
private val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_APP_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
|
||||
private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_APP_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)
|
||||
|
||||
// list of patterns to find some matrix item.
|
||||
val MATRIX_PATTERNS = Arrays.asList(
|
||||
val MATRIX_PATTERNS = listOf(
|
||||
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID,
|
||||
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS,
|
||||
PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID,
|
||||
@ -133,4 +132,4 @@ object MatrixPatterns {
|
||||
fun isGroupId(str: String?): Boolean {
|
||||
return str != null && PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER.matcher(str).matches()
|
||||
}
|
||||
}// Cannot be instantiated
|
||||
}
|
||||
|
@ -70,11 +70,11 @@ data class HomeServerConnectionConfig(
|
||||
if (hsUri.scheme != "http" && hsUri.scheme != "https") {
|
||||
throw RuntimeException("Invalid home server URI: " + hsUri)
|
||||
}
|
||||
// remove trailing /
|
||||
homeServerUri = if (hsUri.toString().endsWith("/")) {
|
||||
// ensure trailing /
|
||||
homeServerUri = if (!hsUri.toString().endsWith("/")) {
|
||||
try {
|
||||
val url = hsUri.toString()
|
||||
Uri.parse(url.substring(0, url.length - 1))
|
||||
Uri.parse("$url/")
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException("Invalid home server URI: $hsUri")
|
||||
}
|
||||
@ -96,11 +96,11 @@ data class HomeServerConnectionConfig(
|
||||
if (identityServerUri.scheme != "http" && identityServerUri.scheme != "https") {
|
||||
throw RuntimeException("Invalid identity server URI: $identityServerUri")
|
||||
}
|
||||
// remove trailing /
|
||||
if (identityServerUri.toString().endsWith("/")) {
|
||||
// ensure trailing /
|
||||
if (!identityServerUri.toString().endsWith("/")) {
|
||||
try {
|
||||
val url = identityServerUri.toString()
|
||||
this.identityServerUri = Uri.parse(url.substring(0, url.length - 1))
|
||||
this.identityServerUri = Uri.parse("$url/")
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException("Invalid identity server URI: $identityServerUri")
|
||||
}
|
||||
|
@ -17,9 +17,6 @@
|
||||
package im.vector.matrix.android.api.permalinks
|
||||
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.widget.TextView
|
||||
import im.vector.matrix.android.api.MatrixPatterns
|
||||
|
||||
/**
|
||||
@ -56,37 +53,5 @@ object MatrixLinkify {
|
||||
}
|
||||
return hasMatch
|
||||
}
|
||||
|
||||
fun addLinks(textView: TextView, callback: MatrixPermalinkSpan.Callback?): Boolean {
|
||||
val text = textView.text
|
||||
if (text is Spannable) {
|
||||
if (addLinks(text, callback)) {
|
||||
addLinkMovementMethod(textView)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
} else {
|
||||
val spannableString = SpannableString.valueOf(text)
|
||||
if (addLinks(spannableString, callback)) {
|
||||
addLinkMovementMethod(textView)
|
||||
textView.text = spannableString
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add linkMovementMethod on textview if not already set
|
||||
* @param textView the textView on which the movementMethod is set
|
||||
*/
|
||||
fun addLinkMovementMethod(textView: TextView) {
|
||||
val movementMethod = textView.movementMethod
|
||||
if (movementMethod == null || movementMethod !is LinkMovementMethod) {
|
||||
if (textView.linksClickable) {
|
||||
textView.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
|
||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.group.GroupService
|
||||
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
||||
import im.vector.matrix.android.api.session.room.RoomService
|
||||
import im.vector.matrix.android.api.session.signout.SignOutService
|
||||
import im.vector.matrix.android.api.session.sync.FilterService
|
||||
@ -34,6 +35,7 @@ import im.vector.matrix.android.api.session.user.UserService
|
||||
*/
|
||||
interface Session :
|
||||
RoomService,
|
||||
RoomDirectoryService,
|
||||
GroupService,
|
||||
UserService,
|
||||
CryptoService,
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* <code>
|
||||
* {
|
||||
* "chunk": [
|
||||
* {
|
||||
* "type": "m.reaction",
|
||||
* "key": "👍",
|
||||
* "count": 3
|
||||
* }
|
||||
* ],
|
||||
* "limited": false,
|
||||
* "count": 1
|
||||
* },
|
||||
* </code>
|
||||
*/
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AggregatedAnnotation (
|
||||
override val limited: Boolean? = false,
|
||||
override val count: Int? = 0,
|
||||
val chunk: List<RelationChunkInfo>? = null
|
||||
|
||||
) : UnsignedRelationInfo
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* <code>
|
||||
* {
|
||||
* "m.annotation": {
|
||||
* "chunk": [
|
||||
* {
|
||||
* "type": "m.reaction",
|
||||
* "key": "👍",
|
||||
* "count": 3
|
||||
* }
|
||||
* ],
|
||||
* "limited": false,
|
||||
* "count": 1
|
||||
* },
|
||||
* "m.reference": {
|
||||
* "chunk": [
|
||||
* {
|
||||
* "type": "m.room.message",
|
||||
* "event_id": "$some_event_id"
|
||||
* }
|
||||
* ],
|
||||
* "limited": false,
|
||||
* "count": 1
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AggregatedRelations(
|
||||
@Json(name = "m.annotation") val annotations: AggregatedAnnotation? = null,
|
||||
@Json(name = "m.reference") val references: DefaultUnsignedRelationInfo? = null
|
||||
)
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class DefaultUnsignedRelationInfo(
|
||||
override val limited: Boolean? = false,
|
||||
override val count: Int? = 0,
|
||||
val chunk: List<Map<String, Any>>? = null
|
||||
|
||||
) : UnsignedRelationInfo
|
@ -31,11 +31,20 @@ typealias Content = JsonDict
|
||||
/**
|
||||
* This methods is a facility method to map a json content to a model.
|
||||
*/
|
||||
inline fun <reified T> Content?.toModel(): T? {
|
||||
inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? {
|
||||
return this?.let {
|
||||
val moshi = MoshiProvider.providesMoshi()
|
||||
val moshiAdapter = moshi.adapter(T::class.java)
|
||||
return moshiAdapter.fromJsonValue(it)
|
||||
return try {
|
||||
moshiAdapter.fromJsonValue(it)
|
||||
} catch (e: Exception) {
|
||||
if (catchError) {
|
||||
Timber.e(e, "To model failed : $e")
|
||||
null
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,9 @@ object EventType {
|
||||
const val KEY_VERIFICATION_MAC = "m.key.verification.mac"
|
||||
const val KEY_VERIFICATION_CANCEL = "m.key.verification.cancel"
|
||||
|
||||
// Relation Events
|
||||
const val REACTION = "m.reaction"
|
||||
|
||||
private val STATE_EVENTS = listOf(
|
||||
STATE_ROOM_NAME,
|
||||
STATE_ROOM_TOPIC,
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* <code>
|
||||
* {
|
||||
* "type": "m.reaction",
|
||||
* "key": "👍",
|
||||
* "count": 3
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RelationChunkInfo(
|
||||
val type: String,
|
||||
val key: String,
|
||||
val count: Int
|
||||
)
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
|
||||
/**
|
||||
* Constants defining known event relation types from Matrix specifications.
|
||||
*/
|
||||
object RelationType {
|
||||
|
||||
/** Lets you define an event which annotates an existing event.*/
|
||||
const val ANNOTATION = "m.annotation"
|
||||
/** Lets you define an event which replaces an existing event.*/
|
||||
const val REPLACE = "m.replace"
|
||||
/** ets you define an event which references an existing event.*/
|
||||
const val REFERENCE = "m.reference"
|
||||
|
||||
}
|
@ -24,5 +24,6 @@ data class UnsignedData(
|
||||
@Json(name = "age") val age: Long?,
|
||||
@Json(name = "redacted_because") val redactedEvent: Event? = null,
|
||||
@Json(name = "transaction_id") val transactionId: String? = null,
|
||||
@Json(name = "prev_content") val prevContent: Map<String, Any>? = null
|
||||
@Json(name = "prev_content") val prevContent: Map<String, Any>? = null,
|
||||
@Json(name = "m.relations") val relations: AggregatedRelations? = null
|
||||
)
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.events.model
|
||||
|
||||
|
||||
interface UnsignedRelationInfo {
|
||||
val limited : Boolean?
|
||||
val count: Int?
|
||||
}
|
@ -18,8 +18,9 @@ package im.vector.matrix.android.api.session.room
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import im.vector.matrix.android.api.session.room.crypto.RoomCryptoService
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationService
|
||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||
import im.vector.matrix.android.api.session.room.send.SendService
|
||||
import im.vector.matrix.android.api.session.room.state.StateService
|
||||
@ -28,11 +29,13 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineService
|
||||
/**
|
||||
* This interface defines methods to interact within a room.
|
||||
*/
|
||||
interface Room : TimelineService,
|
||||
interface Room :
|
||||
TimelineService,
|
||||
SendService,
|
||||
ReadService,
|
||||
RoomMembersService,
|
||||
MembershipService,
|
||||
StateService,
|
||||
RelationService,
|
||||
RoomCryptoService {
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room
|
||||
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* This interface defines methods to get and join public rooms. It's implemented at the session level.
|
||||
*/
|
||||
interface RoomDirectoryService {
|
||||
|
||||
/**
|
||||
* Get rooms from directory
|
||||
*/
|
||||
fun getPublicRooms(server: String?,
|
||||
publicRoomsParams: PublicRoomsParams,
|
||||
callback: MatrixCallback<PublicRoomsResponse>): Cancelable
|
||||
|
||||
/**
|
||||
* Join a room by id
|
||||
*/
|
||||
fun joinRoom(roomId: String,
|
||||
callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Fetches the overall metadata about protocols supported by the homeserver.
|
||||
* Includes both the available protocols and all fields required for queries against each protocol.
|
||||
*/
|
||||
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>)
|
||||
|
||||
}
|
@ -24,9 +24,9 @@ import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* This interface defines methods to retrieve room members of a room. It's implemented at the room level.
|
||||
* This interface defines methods to handling membership. It's implemented at the room level.
|
||||
*/
|
||||
interface RoomMembersService {
|
||||
interface MembershipService {
|
||||
|
||||
/**
|
||||
* This methods load all room members if it was done yet.
|
||||
@ -54,4 +54,15 @@ interface RoomMembersService {
|
||||
*/
|
||||
fun invite(userId: String, callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Join the room
|
||||
*/
|
||||
fun join(callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Leave the room.
|
||||
*
|
||||
*/
|
||||
fun leave(callback: MatrixCallback<Unit>)
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
|
||||
data class EditAggregatedSummary(
|
||||
val aggregatedContent: Content? = null,
|
||||
// The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk)
|
||||
val sourceEvents: List<String>,
|
||||
val localEchos: List<String>,
|
||||
val lastEditTs: Long = 0
|
||||
)
|
@ -13,15 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model
|
||||
|
||||
/**
|
||||
* Represents the membership of the current auth user on a room.
|
||||
*/
|
||||
enum class MyMembership {
|
||||
JOINED,
|
||||
LEFT,
|
||||
INVITED,
|
||||
NONE
|
||||
}
|
||||
data class EventAnnotationsSummary(
|
||||
var eventId: String,
|
||||
var reactionsSummary: List<ReactionAggregatedSummary>,
|
||||
var editSummary: EditAggregatedSummary?
|
||||
)
|
@ -19,10 +19,12 @@ package im.vector.matrix.android.api.session.room.model
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Represents the membership of a user on a room. Linked to a [RoomMember]
|
||||
* Represents the membership of a user on a room
|
||||
*/
|
||||
enum class Membership(val value: String) {
|
||||
|
||||
NONE("none"),
|
||||
|
||||
@Json(name = "invite")
|
||||
INVITE("invite"),
|
||||
|
||||
@ -38,4 +40,8 @@ enum class Membership(val value: String) {
|
||||
@Json(name = "ban")
|
||||
BAN("ban");
|
||||
|
||||
fun isLeft(): Boolean {
|
||||
return this == KNOCK || this == LEAVE || this == BAN
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package im.vector.matrix.android.api.session.room.model
|
||||
|
||||
data class ReactionAggregatedSummary(
|
||||
val key: String, // "👍"
|
||||
val count: Int, // 8
|
||||
val addedByMe: Boolean, // true
|
||||
val firstTimestamp: Long, // unix timestamp
|
||||
val sourceEvents: List<String>,
|
||||
val localEchoEvents: List<String>
|
||||
)
|
@ -31,7 +31,8 @@ data class RoomSummary(
|
||||
val isDirect: Boolean = false,
|
||||
val lastMessage: Event? = null,
|
||||
val otherMemberIds: List<String> = emptyList(),
|
||||
var notificationCount: Int = 0,
|
||||
var highlightCount: Int = 0,
|
||||
var tags: List<RoomTag> = emptyList()
|
||||
val notificationCount: Int = 0,
|
||||
val highlightCount: Int = 0,
|
||||
val tags: List<RoomTag> = emptyList(),
|
||||
val membership: Membership = Membership.NONE
|
||||
)
|
@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class FileInfo(
|
||||
@Json(name = "mimetype") val mimeType: String,
|
||||
@Json(name = "mimetype") val mimeType: String?,
|
||||
@Json(name = "size") val size: Long = 0,
|
||||
@Json(name = "thumbnail_info") val thumbnailInfo: ThumbnailInfo? = null,
|
||||
@Json(name = "thumbnail_url") val thumbnailUrl: String? = null
|
||||
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageAudioContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "info") val info: AudioInfo? = null,
|
||||
@Json(name = "url") val url: String? = null
|
||||
@Json(name = "url") val url: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -16,8 +16,13 @@
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
|
||||
interface MessageContent {
|
||||
val type: String
|
||||
val body: String
|
||||
val relatesTo: RelationDefaultContent?
|
||||
val newContent: Content?
|
||||
}
|
@ -18,9 +18,13 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageDefaultContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageEmoteContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "format") val format: String? = null,
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,6 +18,8 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageFileContent(
|
||||
@ -25,5 +27,7 @@ data class MessageFileContent(
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "filename") val filename: String? = null,
|
||||
@Json(name = "info") val info: FileInfo? = null,
|
||||
@Json(name = "url") val url: String? = null
|
||||
@Json(name = "url") val url: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageImageContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "info") val info: ImageInfo? = null,
|
||||
@Json(name = "url") val url: String? = null
|
||||
@Json(name = "url") val url: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageLocationContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "geo_uri") val geoUri: String,
|
||||
@Json(name = "info") val info: LocationInfo? = null
|
||||
@Json(name = "info") val info: LocationInfo? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageNoticeContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "format") val format: String? = null,
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageTextContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "format") val format: String? = null,
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null
|
||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -18,16 +18,16 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
object MessageType {
|
||||
|
||||
val MSGTYPE_TEXT = "m.text"
|
||||
val MSGTYPE_EMOTE = "m.emote"
|
||||
val MSGTYPE_NOTICE = "m.notice"
|
||||
val MSGTYPE_IMAGE = "m.image"
|
||||
val MSGTYPE_AUDIO = "m.audio"
|
||||
val MSGTYPE_VIDEO = "m.video"
|
||||
val MSGTYPE_LOCATION = "m.location"
|
||||
val MSGTYPE_FILE = "m.file"
|
||||
val FORMAT_MATRIX_HTML = "org.matrix.custom.html"
|
||||
const val MSGTYPE_TEXT = "m.text"
|
||||
const val MSGTYPE_EMOTE = "m.emote"
|
||||
const val MSGTYPE_NOTICE = "m.notice"
|
||||
const val MSGTYPE_IMAGE = "m.image"
|
||||
const val MSGTYPE_AUDIO = "m.audio"
|
||||
const val MSGTYPE_VIDEO = "m.video"
|
||||
const val MSGTYPE_LOCATION = "m.location"
|
||||
const val MSGTYPE_FILE = "m.file"
|
||||
const val FORMAT_MATRIX_HTML = "org.matrix.custom.html"
|
||||
// Add, in local, a fake message type in order to StickerMessage can inherit Message class
|
||||
// Because sticker isn't a message type but a event type without msgtype field
|
||||
val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
|
||||
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
|
||||
}
|
@ -18,11 +18,15 @@ package im.vector.matrix.android.api.session.room.model.message
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class MessageVideoContent(
|
||||
@Json(name = "msgtype") override val type: String,
|
||||
@Json(name = "body") override val body: String,
|
||||
@Json(name = "info") val info: VideoInfo? = null,
|
||||
@Json(name = "url") val url: String? = null
|
||||
@Json(name = "url") val url: String? = null,
|
||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||
) : MessageContent
|
@ -0,0 +1,9 @@
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ReactionContent(
|
||||
@Json(name = "m.relates_to") val relatesTo: ReactionInfo? = null
|
||||
)
|
@ -0,0 +1,13 @@
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ReactionInfo(
|
||||
@Json(name = "rel_type") override val type: String?,
|
||||
@Json(name = "event_id") override val eventId: String,
|
||||
val key: String,
|
||||
//always null for reaction
|
||||
@Json(name = "m.in_reply_to") override val inReplyTo: ReplyToContent? = null
|
||||
) : RelationContent
|
@ -0,0 +1,7 @@
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
interface RelationContent {
|
||||
val type: String?
|
||||
val eventId: String?
|
||||
val inReplyTo: ReplyToContent?
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RelationDefaultContent(
|
||||
@Json(name = "rel_type") override val type: String?,
|
||||
@Json(name = "event_id") override val eventId: String?,
|
||||
@Json(name = "m.in_reply_to") override val inReplyTo: ReplyToContent? = null
|
||||
) : RelationContent
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* In some cases, events may wish to reference other events.
|
||||
* This could be to form a thread of messages for the user to follow along with,
|
||||
* or to provide more context as to what a particular event is describing.
|
||||
* Relation are used to associate new information with an existing event.
|
||||
*
|
||||
* Relations are events which have an m.relates_to mixin in their contents,
|
||||
* and the new information they convey is expressed in their usual event type and content.
|
||||
*
|
||||
* Three types of relations are defined, each defining different behaviour when aggregated:
|
||||
*
|
||||
* m.annotation - lets you define an event which annotates an existing event.
|
||||
* When aggregated, groups events together based on key and returns a count.
|
||||
* (aka SQL's COUNT) These are primarily intended for handling reactions.
|
||||
*
|
||||
* m.replace - lets you define an event which replaces an existing event.
|
||||
* When aggregated, returns the most recent replacement event. (aka SQL's MAX)
|
||||
* These are primarily intended for handling edits.
|
||||
*
|
||||
* m.reference - lets you define an event which references an existing event.
|
||||
* When aggregated, currently doesn't do anything special, but in future could bundle chains of references (i.e. threads).
|
||||
* These are primarily intended for handling replies (and in future threads).
|
||||
*/
|
||||
interface RelationService {
|
||||
|
||||
|
||||
/**
|
||||
* Sends a reaction (emoji) to the targetedEvent.
|
||||
* @param reaction the reaction (preferably emoji)
|
||||
* @param targetEventId the id of the event being reacted
|
||||
*/
|
||||
fun sendReaction(reaction: String, targetEventId: String): Cancelable
|
||||
|
||||
|
||||
/**
|
||||
* Undo a reaction (emoji) to the targetedEvent.
|
||||
* @param reaction the reaction (preferably emoji)
|
||||
* @param targetEventId the id of the event being reacted
|
||||
* @param myUserId used to know if a reaction event was made by the user
|
||||
*/
|
||||
fun undoReaction(reaction: String, targetEventId: String, myUserId: String)//: Cancelable
|
||||
|
||||
|
||||
/**
|
||||
* Update a quick reaction (toggle).
|
||||
* If you have reacted with agree and then you click on disagree, this call will delete(redact)
|
||||
* the disagree and add the agree
|
||||
* If you click on a reaction that you already reacted with, it will undo it
|
||||
* @param reaction the reaction (preferably emoji)
|
||||
* @param oppositeReaction the opposite reaction(preferably emoji)
|
||||
* @param targetEventId the id of the event being reacted
|
||||
* @param myUserId used to know if a reaction event was made by the user
|
||||
*/
|
||||
fun updateQuickReaction(reaction: String, oppositeReaction: String, targetEventId: String, myUserId: String)
|
||||
|
||||
|
||||
/**
|
||||
* Edit a text message body. Limited to "m.text" contentType
|
||||
* @param targetEventId The event to edit
|
||||
* @param newBodyText The edited body
|
||||
* @param compatibilityBodyText The text that will appear on clients that don't support yet edition
|
||||
*/
|
||||
fun editTextMessage(targetEventId: String, newBodyText: String, newBodyAutoMarkdown: Boolean, compatibilityBodyText: String = "* $newBodyText"): Cancelable
|
||||
|
||||
|
||||
/**
|
||||
* Reply to an event in the timeline (must be in same room)
|
||||
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id350
|
||||
* @param eventReplied the event referenced by the reply
|
||||
* @param replyText the reply text
|
||||
*/
|
||||
fun replyToMessage(eventReplied: Event, replyText: String): Cancelable?
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.relation
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ReplyToContent(
|
||||
@Json(name = "event_id") val eventId: String
|
||||
)
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2014 OpenMarket Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.roomdirectory
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Class representing the objects returned by /publicRooms call.
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PublicRoom(
|
||||
|
||||
/**
|
||||
* Aliases of the room. May be empty.
|
||||
*/
|
||||
@Json(name = "aliases")
|
||||
var aliases: List<String>? = null,
|
||||
|
||||
/**
|
||||
* The canonical alias of the room, if any.
|
||||
*/
|
||||
@Json(name = "canonical_alias")
|
||||
var canonicalAlias: String? = null,
|
||||
|
||||
/**
|
||||
* The name of the room, if any.
|
||||
*/
|
||||
@Json(name = "name")
|
||||
var name: String? = null,
|
||||
|
||||
/**
|
||||
* Required. The number of members joined to the room.
|
||||
*/
|
||||
@Json(name = "num_joined_members")
|
||||
var numJoinedMembers: Int = 0,
|
||||
|
||||
/**
|
||||
* Required. The ID of the room.
|
||||
*/
|
||||
@Json(name = "room_id")
|
||||
var roomId: String,
|
||||
|
||||
/**
|
||||
* The topic of the room, if any.
|
||||
*/
|
||||
@Json(name = "topic")
|
||||
var topic: String? = null,
|
||||
|
||||
/**
|
||||
* Required. Whether the room may be viewed by guest users without joining.
|
||||
*/
|
||||
@Json(name = "world_readable")
|
||||
var worldReadable: Boolean = false,
|
||||
|
||||
/**
|
||||
* Required. Whether guest users may join the room and participate in it. If they can, they will be subject to ordinary power level rules like any other user.
|
||||
*/
|
||||
@Json(name = "guest_can_join")
|
||||
var guestCanJoin: Boolean = false,
|
||||
|
||||
/**
|
||||
* The URL for the room's avatar, if one is set.
|
||||
*/
|
||||
@Json(name = "avatar_url")
|
||||
var avatarUrl: String? = null,
|
||||
|
||||
/**
|
||||
* Undocumented item
|
||||
*/
|
||||
@Json(name = "m.federate")
|
||||
var isFederated: Boolean = false
|
||||
|
||||
)
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2014 OpenMarket Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.roomdirectory
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Class to define a filter to retrieve public rooms
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PublicRoomsFilter(
|
||||
/**
|
||||
* A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional).
|
||||
*/
|
||||
@Json(name = "generic_search_term")
|
||||
var searchTerm: String? = null
|
||||
)
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2016 OpenMarket Ltd
|
||||
* Copyright 2017 Vector Creations Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.roomdirectory
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Class to pass parameters to get the public rooms list
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PublicRoomsParams(
|
||||
/**
|
||||
* Limit the number of results returned.
|
||||
*/
|
||||
@Json(name = "limit")
|
||||
var limit: Int? = null,
|
||||
|
||||
/**
|
||||
* A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms.
|
||||
* The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag.
|
||||
*/
|
||||
@Json(name = "since")
|
||||
var since: String? = null,
|
||||
|
||||
/**
|
||||
* Filter to apply to the results.
|
||||
*/
|
||||
@Json(name = "filter")
|
||||
var filter: PublicRoomsFilter? = null,
|
||||
|
||||
/**
|
||||
* Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false.
|
||||
*/
|
||||
@Json(name = "include_all_networks")
|
||||
var includeAllNetworks: Boolean = false,
|
||||
|
||||
/**
|
||||
* The specific third party network/protocol to request from the homeserver. Can only be used if include_all_networks is false.
|
||||
*/
|
||||
@Json(name = "third_party_instance_id")
|
||||
var thirdPartyInstanceId: String? = null
|
||||
)
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2014 OpenMarket Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.api.session.room.model.roomdirectory
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Class representing the public rooms request response
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PublicRoomsResponse(
|
||||
/**
|
||||
* A pagination token for the response. The absence of this token means there are no more results to fetch and the client should stop paginating.
|
||||
*/
|
||||
@Json(name = "next_batch")
|
||||
var nextBatch: String? = null,
|
||||
|
||||
/**
|
||||
* A pagination token that allows fetching previous results. The absence of this token means there are no results before this batch,
|
||||
* i.e. this is the first batch.
|
||||
*/
|
||||
@Json(name = "prev_batch")
|
||||
var prevBatch: String? = null,
|
||||
|
||||
/**
|
||||
* A paginated chunk of public rooms.
|
||||
*/
|
||||
@Json(name = "chunk")
|
||||
var chunk: List<PublicRoom>? = null,
|
||||
|
||||
/**
|
||||
* An estimate on the total number of public rooms, if the server has an estimate.
|
||||
*/
|
||||
@Json(name = "total_room_count_estimate")
|
||||
var totalRoomCountEstimate: Int? = null
|
||||
)
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.thirdparty
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class FieldType(
|
||||
/**
|
||||
* Required. A regular expression for validation of a field's value. This may be relatively coarse to verify the value as the application
|
||||
* service providing this protocol may apply additional
|
||||
*/
|
||||
@Json(name = "regexp")
|
||||
val regexp: String? = null,
|
||||
|
||||
/**
|
||||
* Required. An placeholder serving as a valid example of the field value.
|
||||
*/
|
||||
@Json(name = "placeholder")
|
||||
val placeholder: String? = null
|
||||
)
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.thirdparty
|
||||
|
||||
/**
|
||||
* This class describes a rooms directory server.
|
||||
*/
|
||||
data class RoomDirectoryData(
|
||||
|
||||
/**
|
||||
* The server name (might be null)
|
||||
* Set null when the server is the current user's home server.
|
||||
*/
|
||||
val homeServer: String? = null,
|
||||
|
||||
/**
|
||||
* The display name (the server description)
|
||||
*/
|
||||
val displayName: String = DEFAULT_HOME_SERVER_NAME,
|
||||
|
||||
/**
|
||||
* The third party server identifier
|
||||
*/
|
||||
val thirdPartyInstanceId: String? = null,
|
||||
|
||||
/**
|
||||
* Tell if all the federated servers must be included
|
||||
*/
|
||||
val includeAllNetworks: Boolean = false,
|
||||
|
||||
/**
|
||||
* the avatar url
|
||||
*/
|
||||
val avatarUrl: String? = null
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_HOME_SERVER_NAME = "Matrix"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.thirdparty
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ThirdPartyProtocol(
|
||||
/**
|
||||
* Required. Fields which may be used to identify a third party user. These should be ordered to suggest the way that entities may be grouped,
|
||||
* where higher groupings are ordered first. For example, the name of a network should be searched before the nickname of a user.
|
||||
*/
|
||||
@Json(name = "user_fields")
|
||||
var userFields: List<String>? = null,
|
||||
|
||||
/**
|
||||
* Required. Fields which may be used to identify a third party location. These should be ordered to suggest the way that
|
||||
* entities may be grouped, where higher groupings are ordered first. For example, the name of a network should be
|
||||
* searched before the name of a channel.
|
||||
*/
|
||||
@Json(name = "location_fields")
|
||||
var locationFields: List<String>? = null,
|
||||
|
||||
/**
|
||||
* Required. A content URI representing an icon for the third party protocol.
|
||||
*
|
||||
* FIXDOC: This field was not present in legacy Riot, and it is sometimes sent by the server (no not Required?)
|
||||
*/
|
||||
@Json(name = "icon")
|
||||
var icon: String? = null,
|
||||
|
||||
/**
|
||||
* Required. The type definitions for the fields defined in the user_fields and location_fields. Each entry in those arrays MUST have an entry here.
|
||||
* The string key for this object is field name itself.
|
||||
*
|
||||
* May be an empty object if no fields are defined.
|
||||
*/
|
||||
@Json(name = "field_types")
|
||||
var fieldTypes: Map<String, FieldType>? = null,
|
||||
|
||||
/**
|
||||
* Required. A list of objects representing independent instances of configuration. For example, multiple networks on IRC
|
||||
* if multiple are provided by the same application service.
|
||||
*/
|
||||
@Json(name = "instances")
|
||||
var instances: List<ThirdPartyProtocolInstance>? = null
|
||||
)
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.session.room.model.thirdparty
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ThirdPartyProtocolInstance(
|
||||
/**
|
||||
* Required. A human-readable description for the protocol, such as the name.
|
||||
*/
|
||||
@Json(name = "desc")
|
||||
var desc: String? = null,
|
||||
|
||||
/**
|
||||
* An optional content URI representing the protocol. Overrides the one provided at the higher level Protocol object.
|
||||
*/
|
||||
@Json(name = "icon")
|
||||
var icon: String? = null,
|
||||
|
||||
/**
|
||||
* Required. Preset values for fields the client may use to search by.
|
||||
*/
|
||||
@Json(name = "fields")
|
||||
var fields: Map<String, Any>? = null,
|
||||
|
||||
/**
|
||||
* Required. A unique identifier across all instances.
|
||||
*/
|
||||
@Json(name = "network_id")
|
||||
var networkId: String? = null,
|
||||
|
||||
/**
|
||||
* FIXDOC Not documented on matrix.org doc
|
||||
*/
|
||||
@Json(name = "instance_id")
|
||||
var instanceId: String? = null,
|
||||
|
||||
|
||||
/**
|
||||
* FIXDOC Not documented on matrix.org doc
|
||||
*/
|
||||
@Json(name = "bot_user_id")
|
||||
var botUserId: String? = null
|
||||
)
|
@ -17,6 +17,7 @@
|
||||
package im.vector.matrix.android.api.session.room.send
|
||||
|
||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
@ -30,9 +31,18 @@ interface SendService {
|
||||
* Method to send a text message asynchronously.
|
||||
* @param text the text message to send
|
||||
* @param msgType the message type: MessageType.MSGTYPE_TEXT (default) or MessageType.MSGTYPE_EMOTE
|
||||
* @param autoMarkdown If true, the SDK will generate a formatted HTML message from the body text if markdown syntax is present
|
||||
* @return a [Cancelable]
|
||||
*/
|
||||
fun sendTextMessage(text: String, msgType: String = MessageType.MSGTYPE_TEXT): Cancelable
|
||||
fun sendTextMessage(text: String, msgType: String = MessageType.MSGTYPE_TEXT, autoMarkdown: Boolean = false): Cancelable
|
||||
|
||||
/**
|
||||
* Method to send a text message with a formatted body.
|
||||
* @param text the text message to send
|
||||
* @param formattedText The formatted body using MessageType#FORMAT_MATRIX_HTML
|
||||
* @return a [Cancelable]
|
||||
*/
|
||||
fun sendFormattedTextMessage(text: String,formattedText: String): Cancelable
|
||||
|
||||
/**
|
||||
* Method to send a media asynchronously.
|
||||
@ -48,5 +58,11 @@ interface SendService {
|
||||
*/
|
||||
fun sendMedias(attachments: List<ContentAttachmentData>): Cancelable
|
||||
|
||||
/**
|
||||
* Redacts (delete) the given event.
|
||||
* @param event The event to redact
|
||||
* @param reason Optional reason string
|
||||
*/
|
||||
fun redactEvent(event: Event, reason: String?): Cancelable
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session.room.timeline
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
|
||||
@ -32,7 +33,8 @@ data class TimelineEvent(
|
||||
val displayIndex: Int,
|
||||
val senderName: String?,
|
||||
val senderAvatar: String?,
|
||||
val sendState: SendState
|
||||
val sendState: SendState,
|
||||
val annotations: EventAnnotationsSummary? = null
|
||||
) {
|
||||
|
||||
val metadata = HashMap<String, Any>()
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package im.vector.matrix.android.api.session.user
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
|
||||
/**
|
||||
@ -32,4 +33,11 @@ interface UserService {
|
||||
*/
|
||||
fun getUser(userId: String): User?
|
||||
|
||||
/**
|
||||
* Observe a live user from a userId
|
||||
* @param userId the userId to look for.
|
||||
* @return a Livedata of user with userId
|
||||
*/
|
||||
fun observeUser(userId: String): LiveData<User?>
|
||||
|
||||
}
|
@ -39,7 +39,6 @@ import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import im.vector.matrix.android.internal.crypto.actions.MegolmSessionDataImporter
|
||||
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
||||
import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting
|
||||
@ -62,8 +61,8 @@ import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
|
||||
import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask
|
||||
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.sync.model.SyncResponse
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
@ -116,20 +115,18 @@ internal class CryptoManager(
|
||||
// Actions
|
||||
private val setDeviceVerificationAction: SetDeviceVerificationAction,
|
||||
private val megolmSessionDataImporter: MegolmSessionDataImporter,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
// Repository
|
||||
private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository,
|
||||
// Repository
|
||||
private val megolmEncryptionFactory: MXMegolmEncryptionFactory,
|
||||
private val olmEncryptionFactory: MXOlmEncryptionFactory,
|
||||
// Tasks
|
||||
private val deleteDeviceTask: DeleteDeviceTask,
|
||||
// Tasks
|
||||
private val getDevicesTask: GetDevicesTask,
|
||||
private val setDeviceNameTask: SetDeviceNameTask,
|
||||
private val uploadKeysTask: UploadKeysTask,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val monarchy: Monarchy,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
// TaskExecutor
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : CryptoService {
|
||||
|
||||
|
@ -233,12 +233,11 @@ internal class CryptoModule {
|
||||
olmManager = get(),
|
||||
setDeviceVerificationAction = get(),
|
||||
megolmSessionDataImporter = get(),
|
||||
ensureOlmSessionsForDevicesAction = get(),
|
||||
warnOnUnknownDevicesRepository = get(),
|
||||
megolmEncryptionFactory = get(),
|
||||
olmEncryptionFactory = get(),
|
||||
// Tasks
|
||||
deleteDeviceTask = get(),
|
||||
// Tasks
|
||||
getDevicesTask = get(),
|
||||
setDeviceNameTask = get(),
|
||||
uploadKeysTask = get(),
|
||||
|
@ -86,10 +86,9 @@ internal fun ChunkEntity.add(roomId: String,
|
||||
isUnlinked: Boolean = false) {
|
||||
|
||||
assertIsManaged()
|
||||
if (event.eventId.isNullOrEmpty() || this.events.fastContains(event.eventId)) {
|
||||
if (event.eventId != null && events.fastContains(event.eventId)) {
|
||||
return
|
||||
}
|
||||
|
||||
var currentDisplayIndex = lastDisplayIndex(direction, 0)
|
||||
if (direction == PaginationDirection.FORWARDS) {
|
||||
currentDisplayIndex += 1
|
||||
|
@ -0,0 +1,36 @@
|
||||
package im.vector.matrix.android.internal.database.mapper
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||
import im.vector.matrix.android.api.session.room.model.ReactionAggregatedSummary
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
|
||||
internal object EventAnnotationsSummaryMapper {
|
||||
fun map(annotationsSummary: EventAnnotationsSummaryEntity): EventAnnotationsSummary {
|
||||
return EventAnnotationsSummary(
|
||||
eventId = annotationsSummary.eventId,
|
||||
reactionsSummary = annotationsSummary.reactionsSummary.toList().map {
|
||||
ReactionAggregatedSummary(
|
||||
it.key,
|
||||
it.count,
|
||||
it.addedByMe,
|
||||
it.firstTimestamp,
|
||||
it.sourceEvents.toList(),
|
||||
it.sourceLocalEcho.toList()
|
||||
)
|
||||
},
|
||||
editSummary = annotationsSummary.editSummary?.let {
|
||||
EditAggregatedSummary(
|
||||
ContentMapper.map(it.aggregatedContent),
|
||||
it.sourceEvents.toList(),
|
||||
it.sourceLocalEchoEvents.toList(),
|
||||
it.lastEditTs
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun EventAnnotationsSummaryEntity.asDomain(): EventAnnotationsSummary {
|
||||
return EventAnnotationsSummaryMapper.map(this)
|
||||
}
|
@ -19,14 +19,17 @@ package im.vector.matrix.android.internal.database.mapper
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.UnsignedData
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import java.util.*
|
||||
|
||||
internal object EventMapper {
|
||||
|
||||
|
||||
fun map(event: Event, roomId: String): EventEntity {
|
||||
val uds = if (event.unsignedData == null) null
|
||||
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
|
||||
val eventEntity = EventEntity()
|
||||
eventEntity.eventId = event.eventId ?: ""
|
||||
eventEntity.eventId = event.eventId ?: UUID.randomUUID().toString()
|
||||
eventEntity.roomId = event.roomId ?: roomId
|
||||
eventEntity.content = ContentMapper.map(event.content)
|
||||
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent
|
||||
@ -37,10 +40,14 @@ internal object EventMapper {
|
||||
eventEntity.originServerTs = event.originServerTs
|
||||
eventEntity.redacts = event.redacts
|
||||
eventEntity.age = event.unsignedData?.age ?: event.originServerTs
|
||||
eventEntity.unsignedData = uds
|
||||
return eventEntity
|
||||
}
|
||||
|
||||
fun map(eventEntity: EventEntity): Event {
|
||||
//TODO proxy the event to only parse unsigned data when accessed?
|
||||
var ud = if (eventEntity.unsignedData.isNullOrBlank()) null
|
||||
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).fromJson(eventEntity.unsignedData)
|
||||
return Event(
|
||||
type = eventEntity.type,
|
||||
eventId = eventEntity.eventId,
|
||||
@ -50,7 +57,7 @@ internal object EventMapper {
|
||||
sender = eventEntity.sender,
|
||||
stateKey = eventEntity.stateKey,
|
||||
roomId = eventEntity.roomId,
|
||||
unsignedData = UnsignedData(eventEntity.age),
|
||||
unsignedData = ud,
|
||||
redacts = eventEntity.redacts
|
||||
)
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ internal object RoomSummaryMapper {
|
||||
otherMemberIds = roomSummaryEntity.otherMemberIds.toList(),
|
||||
highlightCount = roomSummaryEntity.highlightCount,
|
||||
notificationCount = roomSummaryEntity.notificationCount,
|
||||
tags = tags
|
||||
tags = tags,
|
||||
membership = roomSummaryEntity.membership
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.database.mapper
|
||||
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.internal.database.model.UserEntity
|
||||
|
||||
internal object UserMapper {
|
||||
|
||||
fun map(userEntity: UserEntity): User {
|
||||
return User(
|
||||
userEntity.userId,
|
||||
userEntity.displayName,
|
||||
userEntity.avatarUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun UserEntity.asDomain(): User {
|
||||
return UserMapper.map(this)
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
|
||||
/**
|
||||
* Keep the latest state of edition of a message
|
||||
*/
|
||||
internal open class EditAggregatedSummaryEntity(
|
||||
var aggregatedContent: String? = null,
|
||||
// The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk)
|
||||
var sourceEvents: RealmList<String> = RealmList(),
|
||||
var sourceLocalEchoEvents: RealmList<String> = RealmList(),
|
||||
var lastEditTs: Long = 0
|
||||
) : RealmObject() {
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
|
||||
internal open class EventAnnotationsSummaryEntity(
|
||||
@PrimaryKey
|
||||
var eventId: String = "",
|
||||
var roomId: String? = null,
|
||||
var reactionsSummary: RealmList<ReactionAggregatedSummaryEntity> = RealmList(),
|
||||
var editSummary: EditAggregatedSummaryEntity? = null
|
||||
) : RealmObject() {
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -36,6 +36,7 @@ internal open class EventEntity(@PrimaryKey var localId: String = UUID.randomUUI
|
||||
var originServerTs: Long? = null,
|
||||
@Index var sender: String? = null,
|
||||
var age: Long? = 0,
|
||||
var unsignedData: String? = null,
|
||||
var redacts: String? = null,
|
||||
@Index var stateIndex: Int = 0,
|
||||
@Index var displayIndex: Int = 0,
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
import io.realm.annotations.PrimaryKey
|
||||
@ -26,10 +26,10 @@ internal open class GroupEntity(@PrimaryKey var groupId: String = ""
|
||||
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = MyMembership.NONE.name
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: MyMembership by Delegates.observable(MyMembership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
|
||||
/**
|
||||
* Aggregated Summary of a reaction.
|
||||
*/
|
||||
internal open class ReactionAggregatedSummaryEntity(
|
||||
// The reaction String 😀
|
||||
var key: String = "",
|
||||
// Number of time this reaction was selected
|
||||
var count: Int = 0,
|
||||
// Did the current user sent this reaction
|
||||
var addedByMe: Boolean = false,
|
||||
// The first time this reaction was added (for ordering purpose)
|
||||
var firstTimestamp: Long = 0,
|
||||
// The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk)
|
||||
var sourceEvents: RealmList<String> = RealmList(),
|
||||
// List of transaction ids for local echos
|
||||
var sourceLocalEcho: RealmList<String> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
@ -30,10 +30,10 @@ internal open class RoomEntity(@PrimaryKey var roomId: String = "",
|
||||
var areAllMembersLoaded: Boolean = false
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = MyMembership.NONE.name
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: MyMembership by Delegates.observable(MyMembership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,12 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.model
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.Ignore
|
||||
import io.realm.annotations.PrimaryKey
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
@ -35,6 +38,13 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var tags: RealmList<RoomTagEntity> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
||||
@delegate:Ignore
|
||||
var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||
membershipStr = newValue.name
|
||||
}
|
||||
|
||||
companion object
|
||||
|
||||
}
|
@ -33,6 +33,9 @@ import io.realm.annotations.RealmModule
|
||||
RoomSummaryEntity::class,
|
||||
RoomTagEntity::class,
|
||||
SyncEntity::class,
|
||||
UserEntity::class
|
||||
UserEntity::class,
|
||||
EventAnnotationsSummaryEntity::class,
|
||||
ReactionAggregatedSummaryEntity::class,
|
||||
EditAggregatedSummaryEntity::class
|
||||
])
|
||||
internal class SessionRealmModule
|
||||
|
@ -0,0 +1,27 @@
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntityFields
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
|
||||
internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
|
||||
val query = realm.where<EventAnnotationsSummaryEntity>()
|
||||
query.equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId)
|
||||
return query
|
||||
}
|
||||
|
||||
internal fun EventAnnotationsSummaryEntity.Companion.whereInRoom(realm: Realm, roomId: String?): RealmQuery<EventAnnotationsSummaryEntity> {
|
||||
val query = realm.where<EventAnnotationsSummaryEntity>()
|
||||
if (roomId != null) {
|
||||
query.equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
|
||||
internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, eventId: String): EventAnnotationsSummaryEntity {
|
||||
val obj = realm.createObject(EventAnnotationsSummaryEntity::class.java, eventId)
|
||||
return obj
|
||||
}
|
@ -52,6 +52,7 @@ internal fun EventEntity.Companion.where(realm: Realm,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun EventEntity.Companion.latestEvent(realm: Realm,
|
||||
roomId: String,
|
||||
includedTypes: List<String> = emptyList(),
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntity
|
||||
import im.vector.matrix.android.internal.database.model.GroupEntityFields
|
||||
import io.realm.Realm
|
||||
@ -27,7 +27,7 @@ internal fun GroupEntity.Companion.where(realm: Realm, roomId: String): RealmQue
|
||||
return realm.where<GroupEntity>().equalTo(GroupEntityFields.GROUP_ID, roomId)
|
||||
}
|
||||
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, membership: MyMembership? = null): RealmQuery<GroupEntity> {
|
||||
internal fun GroupEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<GroupEntity> {
|
||||
val query = realm.where<GroupEntity>()
|
||||
if (membership != null) {
|
||||
query.equalTo(GroupEntityFields.MEMBERSHIP_STR, membership.name)
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntityFields
|
||||
@ -28,7 +28,7 @@ internal fun RoomEntity.Companion.where(realm: Realm, roomId: String): RealmQuer
|
||||
return realm.where<RoomEntity>().equalTo(RoomEntityFields.ROOM_ID, roomId)
|
||||
}
|
||||
|
||||
internal fun RoomEntity.Companion.where(realm: Realm, membership: MyMembership? = null): RealmQuery<RoomEntity> {
|
||||
internal fun RoomEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<RoomEntity> {
|
||||
val query = realm.where<RoomEntity>()
|
||||
if (membership != null) {
|
||||
query.equalTo(RoomEntityFields.MEMBERSHIP_STR, membership.name)
|
||||
|
@ -21,6 +21,7 @@ import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.StringProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
import org.koin.dsl.module.module
|
||||
@ -46,6 +47,9 @@ class MatrixModule(private val context: Context) {
|
||||
single {
|
||||
TaskExecutor(get())
|
||||
}
|
||||
single {
|
||||
StringProvider(context.resources)
|
||||
}
|
||||
|
||||
single {
|
||||
BackgroundDetectionObserver()
|
||||
|
@ -37,13 +37,18 @@ import im.vector.matrix.android.api.session.group.Group
|
||||
import im.vector.matrix.android.api.session.group.GroupService
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
||||
import im.vector.matrix.android.api.session.room.RoomService
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import im.vector.matrix.android.api.session.signout.SignOutService
|
||||
import im.vector.matrix.android.api.session.sync.FilterService
|
||||
import im.vector.matrix.android.api.session.user.UserService
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.api.util.MatrixCallbackDelegate
|
||||
import im.vector.matrix.android.internal.crypto.CryptoManager
|
||||
import im.vector.matrix.android.internal.crypto.CryptoModule
|
||||
@ -78,6 +83,7 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
||||
private val liveEntityUpdaters by inject<List<LiveEntityObserver>>()
|
||||
private val sessionListeners by inject<SessionListeners>()
|
||||
private val roomService by inject<RoomService>()
|
||||
private val roomDirectoryService by inject<RoomDirectoryService>()
|
||||
private val groupService by inject<GroupService>()
|
||||
private val userService by inject<UserService>()
|
||||
private val filterService by inject<FilterService>()
|
||||
@ -195,6 +201,23 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
||||
return roomService.liveRoomSummaries()
|
||||
}
|
||||
|
||||
// ROOM DIRECTORY SERVICE
|
||||
|
||||
override fun getPublicRooms(server: String?, publicRoomsParams: PublicRoomsParams, callback: MatrixCallback<PublicRoomsResponse>): Cancelable {
|
||||
assert(isOpen)
|
||||
return roomDirectoryService.getPublicRooms(server, publicRoomsParams, callback)
|
||||
}
|
||||
|
||||
override fun joinRoom(roomId: String, callback: MatrixCallback<Unit>) {
|
||||
assert(isOpen)
|
||||
return roomDirectoryService.joinRoom(roomId, callback)
|
||||
}
|
||||
|
||||
override fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>) {
|
||||
assert(isOpen)
|
||||
return roomDirectoryService.getThirdPartyProtocol(callback)
|
||||
}
|
||||
|
||||
// GROUP SERVICE
|
||||
|
||||
override fun getGroup(groupId: String): Group? {
|
||||
@ -232,6 +255,11 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi
|
||||
return userService.getUser(userId)
|
||||
}
|
||||
|
||||
override fun observeUser(userId: String): LiveData<User?> {
|
||||
assert(isOpen)
|
||||
return userService.observeUser(userId)
|
||||
}
|
||||
|
||||
// CRYPTO SERVICE
|
||||
|
||||
override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
|
||||
|
@ -21,6 +21,7 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
import im.vector.matrix.android.api.session.cache.CacheService
|
||||
import im.vector.matrix.android.api.session.group.GroupService
|
||||
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
||||
import im.vector.matrix.android.api.session.room.RoomService
|
||||
import im.vector.matrix.android.api.session.signout.SignOutService
|
||||
import im.vector.matrix.android.api.session.sync.FilterService
|
||||
@ -33,11 +34,13 @@ import im.vector.matrix.android.internal.session.cache.RealmClearCacheTask
|
||||
import im.vector.matrix.android.internal.session.filter.*
|
||||
import im.vector.matrix.android.internal.session.group.DefaultGroupService
|
||||
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
|
||||
import im.vector.matrix.android.internal.session.room.DefaultRoomService
|
||||
import im.vector.matrix.android.internal.session.room.RoomAvatarResolver
|
||||
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.*
|
||||
import im.vector.matrix.android.internal.session.room.directory.DefaultGetPublicRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.directory.DefaultGetThirdPartyProtocolsTask
|
||||
import im.vector.matrix.android.internal.session.room.directory.GetPublicRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.directory.GetThirdPartyProtocolsTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMemberDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.prune.EventsPruner
|
||||
import im.vector.matrix.android.internal.session.signout.DefaultSignOutService
|
||||
import im.vector.matrix.android.internal.session.user.DefaultUserService
|
||||
@ -106,6 +109,18 @@ internal class SessionModule(private val sessionParams: SessionParams) {
|
||||
DefaultRoomService(get(), get(), get(), get()) as RoomService
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultGetPublicRoomTask(get()) as GetPublicRoomTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultGetThirdPartyProtocolsTask(get()) as GetThirdPartyProtocolsTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultRoomDirectoryService(get(), get(), get(), get()) as RoomDirectoryService
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultGroupService(get()) as GroupService
|
||||
}
|
||||
@ -149,9 +164,11 @@ internal class SessionModule(private val sessionParams: SessionParams) {
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
val groupSummaryUpdater = GroupSummaryUpdater(get())
|
||||
val eventsPruner = EventsPruner(get())
|
||||
val userEntityUpdater = UserEntityUpdater(get(), get(), get())
|
||||
listOf<LiveEntityObserver>(groupSummaryUpdater, eventsPruner, userEntityUpdater)
|
||||
val aggregationUpdater = EventRelationsAggregationUpdater(get(), get(), get(), get())
|
||||
//Event pruner must be the last one, because it will clear contents
|
||||
val eventsPruner = EventsPruner(get(), get(), get(), get())
|
||||
listOf<LiveEntityObserver>(groupSummaryUpdater, userEntityUpdater, aggregationUpdater, eventsPruner)
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,10 +21,19 @@ import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
|
||||
|
||||
private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
|
||||
internal const val URI_PREFIX_CONTENT_API = "/_matrix/media/v1/"
|
||||
private const val URI_PREFIX_CONTENT_API = "_matrix/media/v1/"
|
||||
|
||||
internal class DefaultContentUrlResolver(private val homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
|
||||
|
||||
companion object {
|
||||
fun getUploadUrl(homeServerConnectionConfig: HomeServerConnectionConfig): String {
|
||||
val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
|
||||
val sep = if (baseUrl.endsWith("/")) "" else "/"
|
||||
|
||||
return baseUrl + sep + URI_PREFIX_CONTENT_API + "upload"
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveFullSize(contentUrl: String?): String? {
|
||||
if (contentUrl?.isValidMatrixContentUrl() == true) {
|
||||
val baseUrl = homeServerConnectionConfig.homeServerUri.toString()
|
||||
@ -57,7 +66,10 @@ internal class DefaultContentUrlResolver(private val homeServerConnectionConfig:
|
||||
fragment = serverAndMediaId.substring(fragmentOffset)
|
||||
serverAndMediaId = serverAndMediaId.substring(0, fragmentOffset)
|
||||
}
|
||||
return baseUrl + prefix + serverAndMediaId + (params ?: "") + fragment
|
||||
|
||||
val sep = if (baseUrl.endsWith("/")) "" else "/"
|
||||
|
||||
return baseUrl + sep + prefix + serverAndMediaId + (params ?: "") + fragment
|
||||
}
|
||||
|
||||
private fun String.isValidMatrixContentUrl(): Boolean {
|
||||
|
@ -21,19 +21,15 @@ import arrow.core.Try.Companion.raise
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import im.vector.matrix.android.internal.network.ProgressRequestBody
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.*
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
internal class FileUploader(private val okHttpClient: OkHttpClient,
|
||||
private val sessionParams: SessionParams) {
|
||||
sessionParams: SessionParams) {
|
||||
|
||||
private val uploadUrl = sessionParams.homeServerConnectionConfig.homeServerUri.toString() + URI_PREFIX_CONTENT_API + "upload"
|
||||
private val uploadUrl = DefaultContentUrlResolver.getUploadUrl(sessionParams.homeServerConnectionConfig)
|
||||
|
||||
private val moshi = MoshiProvider.providesMoshi()
|
||||
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
|
||||
@ -82,7 +78,7 @@ internal class FileUploader(private val okHttpClient: OkHttpClient,
|
||||
response.body()?.source()?.let {
|
||||
responseAdapter.fromJson(it)
|
||||
}
|
||||
?: throw IOException()
|
||||
?: throw IOException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationService
|
||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||
import im.vector.matrix.android.api.session.room.send.SendService
|
||||
import im.vector.matrix.android.api.session.room.state.StateService
|
||||
@ -40,14 +41,16 @@ internal class DefaultRoom(
|
||||
private val sendService: SendService,
|
||||
private val stateService: StateService,
|
||||
private val readService: ReadService,
|
||||
private val roomMembersService: RoomMembersService,
|
||||
private val cryptoService: CryptoService
|
||||
private val cryptoService: CryptoService,
|
||||
private val relationService: RelationService,
|
||||
private val roomMembersService: MembershipService
|
||||
) : Room,
|
||||
TimelineService by timelineService,
|
||||
SendService by sendService,
|
||||
StateService by stateService,
|
||||
ReadService by readService,
|
||||
RoomMembersService by roomMembersService {
|
||||
RelationService by relationService,
|
||||
MembershipService by roomMembersService {
|
||||
|
||||
override val roomSummary: LiveData<RoomSummary> by lazy {
|
||||
val liveRealmData = RealmLiveData<RoomSummaryEntity>(monarchy.realmConfiguration) { realm ->
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.session.room.directory.GetPublicRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.directory.GetThirdPartyProtocolsTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
|
||||
internal class DefaultRoomDirectoryService(private val getPublicRoomTask: GetPublicRoomTask,
|
||||
private val joinRoomTask: JoinRoomTask,
|
||||
private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask,
|
||||
private val taskExecutor: TaskExecutor) : RoomDirectoryService {
|
||||
|
||||
override fun getPublicRooms(server: String?,
|
||||
publicRoomsParams: PublicRoomsParams,
|
||||
callback: MatrixCallback<PublicRoomsResponse>): Cancelable {
|
||||
return getPublicRoomTask
|
||||
.configureWith(GetPublicRoomTask.Params(server, publicRoomsParams))
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun joinRoom(roomId: String, callback: MatrixCallback<Unit>) {
|
||||
joinRoomTask
|
||||
.configureWith(JoinRoomTask.Params(roomId))
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>) {
|
||||
getThirdPartyProtocolsTask
|
||||
.configureWith(Unit)
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import io.realm.Realm
|
||||
|
||||
/**
|
||||
* Fetches annotations (reactions, edits...) associated to a given eventEntity from the data layer.
|
||||
*/
|
||||
internal class EventRelationExtractor {
|
||||
|
||||
fun extractFrom(event: EventEntity, realm: Realm = event.realm): EventAnnotationsSummary? {
|
||||
return EventAnnotationsSummaryEntity.where(realm, event.eventId).findFirst()?.asDomain()
|
||||
}
|
||||
}
|
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import arrow.core.Try
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.events.model.*
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.relation.ReactionContent
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
||||
import im.vector.matrix.android.internal.database.model.*
|
||||
import im.vector.matrix.android.internal.database.query.create
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.tryTransactionAsync
|
||||
import io.realm.Realm
|
||||
import timber.log.Timber
|
||||
|
||||
internal interface EventRelationsAggregationTask : Task<EventRelationsAggregationTask.Params, Unit> {
|
||||
|
||||
data class Params(
|
||||
val events: List<Pair<Event, SendState>>,
|
||||
val userId: String
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base.
|
||||
*/
|
||||
internal class DefaultEventRelationsAggregationTask(private val monarchy: Monarchy) : EventRelationsAggregationTask {
|
||||
|
||||
override suspend fun execute(params: EventRelationsAggregationTask.Params): Try<Unit> {
|
||||
return monarchy.tryTransactionAsync { realm ->
|
||||
update(realm, params.events, params.userId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun update(realm: Realm, events: List<Pair<Event, SendState>>, userId: String) {
|
||||
events.forEach { pair ->
|
||||
val roomId = pair.first.roomId ?: return@forEach
|
||||
val event = pair.first
|
||||
val sendState = pair.second
|
||||
val isLocalEcho = sendState == SendState.UNSENT
|
||||
when (event.type) {
|
||||
EventType.REACTION -> {
|
||||
//we got a reaction!!
|
||||
Timber.v("###REACTION in room $roomId")
|
||||
handleReaction(event, roomId, realm, userId, isLocalEcho)
|
||||
}
|
||||
EventType.MESSAGE -> {
|
||||
if (event.unsignedData?.relations?.annotations != null) {
|
||||
Timber.v("###REACTION Agreggation in room $roomId for event ${event.eventId}")
|
||||
handleInitialAggregatedRelations(event, roomId, event.unsignedData.relations.annotations, realm)
|
||||
} else {
|
||||
val content: MessageContent? = event.content.toModel()
|
||||
if (content?.relatesTo?.type == RelationType.REPLACE) {
|
||||
Timber.v("###REPLACE in room $roomId for event ${event.eventId}")
|
||||
//A replace!
|
||||
handleReplace(realm, event, content, roomId, isLocalEcho)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
EventType.REDACTION -> {
|
||||
val eventToPrune = event.redacts?.let { EventEntity.where(realm, eventId = it).findFirst() }
|
||||
?: return
|
||||
when (eventToPrune.type) {
|
||||
EventType.MESSAGE -> {
|
||||
Timber.d("REDACTION for message ${eventToPrune.eventId}")
|
||||
val unsignedData = EventMapper.map(eventToPrune).unsignedData
|
||||
?: UnsignedData(null, null)
|
||||
|
||||
//was this event a m.replace
|
||||
val contentModel = ContentMapper.map(eventToPrune.content)?.toModel<MessageContent>()
|
||||
if (RelationType.REPLACE == contentModel?.relatesTo?.type && contentModel.relatesTo?.eventId != null) {
|
||||
handleRedactionOfReplace(eventToPrune, contentModel.relatesTo!!.eventId!!, realm)
|
||||
}
|
||||
|
||||
}
|
||||
EventType.REACTION -> {
|
||||
handleReactionRedact(eventToPrune, realm, userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReplace(realm: Realm, event: Event, content: MessageContent, roomId: String, isLocalEcho: Boolean) {
|
||||
val eventId = event.eventId ?: return
|
||||
val targetEventId = content.relatesTo?.eventId ?: return
|
||||
val newContent = content.newContent ?: return
|
||||
//ok, this is a replace
|
||||
var existing = EventAnnotationsSummaryEntity.where(realm, targetEventId).findFirst()
|
||||
if (existing == null) {
|
||||
Timber.v("###REPLACE creating no relation summary for ${targetEventId}")
|
||||
existing = EventAnnotationsSummaryEntity.create(realm, targetEventId)
|
||||
existing.roomId = roomId
|
||||
}
|
||||
|
||||
//we have it
|
||||
val existingSummary = existing.editSummary
|
||||
if (existingSummary == null) {
|
||||
Timber.v("###REPLACE no edit summary for ${targetEventId}, creating one (localEcho:$isLocalEcho)")
|
||||
//create the edit summary
|
||||
val editSummary = realm.createObject(EditAggregatedSummaryEntity::class.java)
|
||||
editSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis()
|
||||
editSummary.aggregatedContent = ContentMapper.map(newContent)
|
||||
if (isLocalEcho) {
|
||||
editSummary.sourceLocalEchoEvents.add(eventId)
|
||||
} else {
|
||||
editSummary.sourceEvents.add(eventId)
|
||||
}
|
||||
|
||||
existing.editSummary = editSummary
|
||||
} else {
|
||||
if (existingSummary.sourceEvents.contains(eventId)) {
|
||||
//ignore this event, we already know it (??)
|
||||
Timber.v("###REPLACE ignoring event for summary, it's known ${eventId}")
|
||||
return
|
||||
}
|
||||
val txId = event.unsignedData?.transactionId
|
||||
//is it a remote echo?
|
||||
if (!isLocalEcho && existingSummary.sourceLocalEchoEvents.contains(txId)) {
|
||||
//ok it has already been managed
|
||||
Timber.v("###REPLACE Receiving remote echo of edit (edit already done)")
|
||||
existingSummary.sourceLocalEchoEvents.remove(txId)
|
||||
existingSummary.sourceEvents.add(event.eventId)
|
||||
} else if (event.originServerTs ?: 0 > existingSummary.lastEditTs) {
|
||||
Timber.v("###REPLACE Computing aggregated edit summary (isLocalEcho:$isLocalEcho)")
|
||||
existingSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis()
|
||||
existingSummary.aggregatedContent = ContentMapper.map(newContent)
|
||||
existingSummary.sourceEvents.add(eventId)
|
||||
} else {
|
||||
//ignore this event for the summary
|
||||
Timber.v("###REPLACE ignoring event for summary, it's to old ${eventId}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun handleInitialAggregatedRelations(event: Event, roomId: String, aggregation: AggregatedAnnotation, realm: Realm) {
|
||||
aggregation.chunk?.forEach {
|
||||
if (it.type == EventType.REACTION) {
|
||||
val eventId = event.eventId ?: ""
|
||||
val existing = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
||||
if (existing == null) {
|
||||
val eventSummary = EventAnnotationsSummaryEntity.create(realm, eventId)
|
||||
eventSummary.roomId = roomId
|
||||
val sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java)
|
||||
sum.key = it.key
|
||||
sum.firstTimestamp = event.originServerTs ?: 0 //TODO how to maintain order?
|
||||
sum.count = it.count
|
||||
eventSummary.reactionsSummary.add(sum)
|
||||
} else {
|
||||
//TODO how to handle that
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReaction(event: Event, roomId: String, realm: Realm, userId: String, isLocalEcho: Boolean) {
|
||||
event.content.toModel<ReactionContent>()?.let { content ->
|
||||
//rel_type must be m.annotation
|
||||
if (RelationType.ANNOTATION == content.relatesTo?.type) {
|
||||
val reaction = content.relatesTo.key
|
||||
val eventId = content.relatesTo.eventId
|
||||
val eventSummary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
||||
?: EventAnnotationsSummaryEntity.create(realm, eventId).apply { this.roomId = roomId }
|
||||
|
||||
var sum = eventSummary.reactionsSummary.find { it.key == reaction }
|
||||
val txId = event.unsignedData?.transactionId
|
||||
if (isLocalEcho && txId.isNullOrBlank()) {
|
||||
Timber.w("Received a local echo with no transaction ID")
|
||||
}
|
||||
if (sum == null) {
|
||||
sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java)
|
||||
sum.key = reaction
|
||||
sum.firstTimestamp = event.originServerTs ?: 0
|
||||
if (isLocalEcho) {
|
||||
Timber.v("Adding local echo reaction $reaction")
|
||||
sum.sourceLocalEcho.add(txId)
|
||||
sum.count = 1
|
||||
} else {
|
||||
Timber.v("Adding synced reaction $reaction")
|
||||
sum.count = 1
|
||||
sum.sourceEvents.add(event.eventId)
|
||||
}
|
||||
sum.addedByMe = sum.addedByMe || (userId == event.sender)
|
||||
eventSummary.reactionsSummary.add(sum)
|
||||
} else {
|
||||
//is this a known event (is possible? pagination?)
|
||||
if (!sum.sourceEvents.contains(eventId)) {
|
||||
|
||||
//check if it's not the sync of a local echo
|
||||
if (!isLocalEcho && sum.sourceLocalEcho.contains(txId)) {
|
||||
//ok it has already been counted, just sync the list, do not touch count
|
||||
Timber.v("Ignoring synced of local echo for reaction $reaction")
|
||||
sum.sourceLocalEcho.remove(txId)
|
||||
sum.sourceEvents.add(event.eventId)
|
||||
} else {
|
||||
sum.count += 1
|
||||
if (isLocalEcho) {
|
||||
Timber.v("Adding local echo reaction $reaction")
|
||||
sum.sourceLocalEcho.add(txId)
|
||||
} else {
|
||||
Timber.v("Adding synced reaction $reaction")
|
||||
sum.sourceEvents.add(event.eventId)
|
||||
}
|
||||
|
||||
sum.addedByMe = sum.addedByMe || (userId == event.sender)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an event is deleted
|
||||
*/
|
||||
private fun handleRedactionOfReplace(redacted: EventEntity, relatedEventId: String, realm: Realm) {
|
||||
Timber.d("Handle redaction of m.replace")
|
||||
val eventSummary = EventAnnotationsSummaryEntity.where(realm, relatedEventId).findFirst()
|
||||
if (eventSummary == null) {
|
||||
Timber.w("Redaction of a replace targeting an unknown event $relatedEventId")
|
||||
return
|
||||
}
|
||||
val sourceEvents = eventSummary.editSummary?.sourceEvents
|
||||
val sourceToDiscard = sourceEvents?.indexOf(redacted.eventId)
|
||||
if (sourceToDiscard == null) {
|
||||
Timber.w("Redaction of a replace that was not known in aggregation $sourceToDiscard")
|
||||
return
|
||||
}
|
||||
//Need to remove this event from the redaction list and compute new aggregation state
|
||||
sourceEvents.removeAt(sourceToDiscard)
|
||||
val previousEdit = sourceEvents.mapNotNull { EventEntity.where(realm, it).findFirst() }.sortedBy { it.originServerTs }.lastOrNull()
|
||||
if (previousEdit == null) {
|
||||
//revert to original
|
||||
eventSummary.editSummary?.deleteFromRealm()
|
||||
} else {
|
||||
//I have the last event
|
||||
ContentMapper.map(previousEdit.content)?.toModel<MessageContent>()?.newContent?.let { newContent ->
|
||||
eventSummary.editSummary?.lastEditTs = previousEdit.originServerTs
|
||||
?: System.currentTimeMillis()
|
||||
eventSummary.editSummary?.aggregatedContent = ContentMapper.map(newContent)
|
||||
} ?: run {
|
||||
Timber.e("Failed to udate edited summary")
|
||||
//TODO how to reccover that
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun handleReactionRedact(eventToPrune: EventEntity, realm: Realm, userId: String) {
|
||||
Timber.v("REDACTION of reaction ${eventToPrune.eventId}")
|
||||
//delete a reaction, need to update the annotation summary if any
|
||||
val reactionContent: ReactionContent = EventMapper.map(eventToPrune).content.toModel()
|
||||
?: return
|
||||
val eventThatWasReacted = reactionContent.relatesTo?.eventId ?: return
|
||||
|
||||
val reactionKey = reactionContent.relatesTo.key
|
||||
Timber.v("REMOVE reaction for key $reactionKey")
|
||||
val summary = EventAnnotationsSummaryEntity.where(realm, eventThatWasReacted).findFirst()
|
||||
if (summary != null) {
|
||||
summary.reactionsSummary.where()
|
||||
.equalTo(ReactionAggregatedSummaryEntityFields.KEY, reactionKey)
|
||||
.findFirst()?.let { aggregation ->
|
||||
Timber.v("Find summary for key with ${aggregation.sourceEvents.size} known reactions (count:${aggregation.count})")
|
||||
Timber.v("Known reactions ${aggregation.sourceEvents.joinToString(",")}")
|
||||
if (aggregation.sourceEvents.contains(eventToPrune.eventId)) {
|
||||
Timber.v("REMOVE reaction for key $reactionKey")
|
||||
aggregation.sourceEvents.remove(eventToPrune.eventId)
|
||||
Timber.v("Known reactions after ${aggregation.sourceEvents.joinToString(",")}")
|
||||
aggregation.count = aggregation.count - 1
|
||||
if (eventToPrune.sender == userId) {
|
||||
//Was it a redact on my reaction?
|
||||
aggregation.addedByMe = false
|
||||
}
|
||||
if (aggregation.count == 0) {
|
||||
//delete!
|
||||
aggregation.deleteFromRealm()
|
||||
}
|
||||
} else {
|
||||
Timber.e("## Cannot remove summary from count, corresponding reaction ${eventToPrune.eventId} is not known")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.e("## Cannot find summary for key $reactionKey")
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Acts as a listener of incoming messages in order to incrementally computes a summary of annotations.
|
||||
* For reactions will build a EventAnnotationsSummaryEntity, ans for edits a EditAggregatedSummaryEntity.
|
||||
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
|
||||
*/
|
||||
internal class EventRelationsAggregationUpdater(monarchy: Monarchy,
|
||||
private val credentials: Credentials,
|
||||
private val task: EventRelationsAggregationTask,
|
||||
private val taskExecutor: TaskExecutor) :
|
||||
RealmLiveEntityObserver<EventEntity>(monarchy) {
|
||||
|
||||
override val query = Monarchy.Query<EventEntity> {
|
||||
EventEntity.where(it)
|
||||
//mmm why is this query not working?
|
||||
// EventEntity.byTypes(it, listOf(
|
||||
// EventType.REDACTION, EventType.MESSAGE, EventType.REDACTION)
|
||||
// )
|
||||
}
|
||||
|
||||
override fun processChanges(inserted: List<EventEntity>, updated: List<EventEntity>, deleted: List<EventEntity>) {
|
||||
Timber.v("EventRelationsAggregationUpdater called with ${inserted.size} insertions")
|
||||
val inserted = inserted
|
||||
.mapNotNull { it.asDomain() to it.sendState }
|
||||
|
||||
val params = EventRelationsAggregationTask.Params(
|
||||
inserted,
|
||||
credentials.userId
|
||||
)
|
||||
|
||||
task.configureWith(params)
|
||||
.executeBy(taskExecutor)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,9 +20,12 @@ import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomResponse
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteBody
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembersResponse
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembersResponse
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteBody
|
||||
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import im.vector.matrix.android.internal.session.room.send.SendResponse
|
||||
import im.vector.matrix.android.internal.session.room.timeline.EventContextResponse
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse
|
||||
@ -31,6 +34,25 @@ import retrofit2.http.*
|
||||
|
||||
internal interface RoomAPI {
|
||||
|
||||
/**
|
||||
* Get the third party server protocols.
|
||||
*
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-thirdparty-protocols
|
||||
*/
|
||||
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols")
|
||||
fun thirdPartyProtocols(): Call<Map<String, ThirdPartyProtocol>>
|
||||
|
||||
/**
|
||||
* Lists the public rooms on the server, with optional filter.
|
||||
* This API returns paginated responses. The rooms are ordered by the number of joined members, with the largest rooms first.
|
||||
*
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-publicrooms
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "publicRooms")
|
||||
fun publicRooms(@Query("server") server: String?,
|
||||
@Body publicRoomsParams: PublicRoomsParams
|
||||
): Call<PublicRoomsResponse>
|
||||
|
||||
/**
|
||||
* Create a room.
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-createroom
|
||||
@ -156,4 +178,58 @@ internal interface RoomAPI {
|
||||
@Path("state_event_type") stateEventType: String,
|
||||
@Path("state_key") stateKey: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
|
||||
/**
|
||||
* Send a relation event to a room.
|
||||
*
|
||||
* @param txId the transaction Id
|
||||
* @param roomId the room id
|
||||
* @param eventType the event type
|
||||
* @param content the event content
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}")
|
||||
fun sendRelation(@Path("roomId") roomId: String,
|
||||
@Path("parentId") parent_id: String,
|
||||
@Path("relation_type") relationType: String,
|
||||
@Path("eventType") eventType: String,
|
||||
@Body content: Content?
|
||||
): Call<SendResponse>
|
||||
|
||||
/**
|
||||
* Join the given room.
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param params the request body
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/join")
|
||||
fun join(@Path("roomId") roomId: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
|
||||
/**
|
||||
* Leave the given room.
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param params the request body
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave")
|
||||
fun leave(@Path("roomId") roomId: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
|
||||
/**
|
||||
* Strips all information out of an event which isn't critical to the integrity of the server-side representation of the room.
|
||||
* This cannot be undone.
|
||||
* Users may redact their own events, and any user with a power level greater than or equal to the redact power level of the room may redact events there.
|
||||
*
|
||||
* @param txId the transaction Id
|
||||
* @param roomId the room id
|
||||
* @param eventId the event to delete
|
||||
* @param reason json containing reason key {"reason": "Indecent material"}
|
||||
*/
|
||||
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/redact/{eventId}/{txnId}")
|
||||
fun redactEvent(
|
||||
@Path("txnId") txId: String,
|
||||
@Path("roomId") roomId: String,
|
||||
@Path("eventId") parent_id: String,
|
||||
@Body reason: Map<String, String>
|
||||
): Call<SendResponse>
|
||||
}
|
@ -20,14 +20,14 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomAvatarContent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
|
||||
internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
private val credentials: Credentials) {
|
||||
@ -48,7 +48,7 @@ internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
}
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val members = roomMembers.getLoaded()
|
||||
if (roomEntity?.membership == MyMembership.INVITED) {
|
||||
if (roomEntity?.membership == Membership.INVITE) {
|
||||
if (members.size == 1) {
|
||||
res = members.entries.first().value.avatarUrl
|
||||
} else if (members.size > 1) {
|
||||
@ -57,9 +57,9 @@ internal class RoomAvatarResolver(private val monarchy: Monarchy,
|
||||
}
|
||||
} else {
|
||||
// detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat)
|
||||
if (roomMembers.getNumberOfJoinedMembers() == 1 && members.isNotEmpty()) {
|
||||
if (members.size == 1) {
|
||||
res = members.entries.first().value.avatarUrl
|
||||
} else if (roomMembers.getNumberOfMembers() == 2 && members.size > 1) {
|
||||
} else if (members.size == 2) {
|
||||
val firstOtherMember = members.filterKeys { it != credentials.userId }.values.firstOrNull()
|
||||
res = firstOtherMember?.avatarUrl
|
||||
}
|
||||
|
@ -19,13 +19,17 @@ package im.vector.matrix.android.internal.session.room
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.internal.crypto.CryptoManager
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.members.DefaultRoomMembersService
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.read.DefaultReadService
|
||||
import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.DefaultRelationService
|
||||
import im.vector.matrix.android.internal.session.room.relation.FindReactionEventForUndoTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.UpdateQuickReactionTask
|
||||
import im.vector.matrix.android.internal.session.room.send.DefaultSendService
|
||||
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
|
||||
import im.vector.matrix.android.internal.session.room.state.DefaultStateService
|
||||
@ -36,25 +40,31 @@ import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TimelineEventFactory
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
|
||||
internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
internal class RoomFactory(private val monarchy: Monarchy,
|
||||
private val eventFactory: LocalEchoEventFactory,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val monarchy: Monarchy,
|
||||
private val paginationTask: PaginationTask,
|
||||
private val contextOfEventTask: GetContextOfEventTask,
|
||||
private val setReadMarkersTask: SetReadMarkersTask,
|
||||
private val eventFactory: LocalEchoEventFactory,
|
||||
private val cryptoService: CryptoService,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
|
||||
private val updateQuickReactionTask: UpdateQuickReactionTask,
|
||||
private val joinRoomTask: JoinRoomTask,
|
||||
private val leaveRoomTask: LeaveRoomTask) {
|
||||
|
||||
fun instantiate(roomId: String): Room {
|
||||
val roomMemberExtractor = SenderRoomMemberExtractor(roomId)
|
||||
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, cryptoService)
|
||||
val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, contextOfEventTask, timelineEventFactory, paginationTask)
|
||||
val relationExtractor = EventRelationExtractor()
|
||||
val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, relationExtractor, cryptoService)
|
||||
val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, timelineEventFactory, contextOfEventTask, paginationTask)
|
||||
val sendService = DefaultSendService(roomId, eventFactory, cryptoService, monarchy)
|
||||
val stateService = DefaultStateService(roomId, sendStateTask, taskExecutor)
|
||||
val roomMembersService = DefaultRoomMembersService(roomId, monarchy, loadRoomMembersTask, inviteTask, taskExecutor)
|
||||
val readService = DefaultReadService(roomId, monarchy, setReadMarkersTask, taskExecutor)
|
||||
val stateService = DefaultStateService(roomId, taskExecutor, sendStateTask)
|
||||
val roomMembersService = DefaultMembershipService(roomId, monarchy, taskExecutor, loadRoomMembersTask, inviteTask, joinRoomTask, leaveRoomTask)
|
||||
val readService = DefaultReadService(roomId, monarchy, taskExecutor, setReadMarkersTask)
|
||||
val reactionService = DefaultRelationService(roomId, eventFactory, findReactionEventForUndoTask, updateQuickReactionTask, monarchy, taskExecutor)
|
||||
|
||||
return DefaultRoom(
|
||||
roomId,
|
||||
@ -63,8 +73,9 @@ internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
sendService,
|
||||
stateService,
|
||||
readService,
|
||||
roomMembersService,
|
||||
cryptoService
|
||||
cryptoService,
|
||||
reactionService,
|
||||
roomMembersService
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -19,20 +19,26 @@ package im.vector.matrix.android.internal.session.room
|
||||
import im.vector.matrix.android.internal.session.DefaultSession
|
||||
import im.vector.matrix.android.internal.session.room.create.CreateRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.create.DefaultCreateRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.invite.DefaultInviteTask
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.members.DefaultLoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.DefaultLoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.DefaultInviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.DefaultJoinRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.DefaultLeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.prune.DefaultPruneEventTask
|
||||
import im.vector.matrix.android.internal.session.room.prune.PruneEventTask
|
||||
import im.vector.matrix.android.internal.session.room.read.DefaultSetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.DefaultFindReactionEventForUndoTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.DefaultUpdateQuickReactionTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.FindReactionEventForUndoTask
|
||||
import im.vector.matrix.android.internal.session.room.relation.UpdateQuickReactionTask
|
||||
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
|
||||
import im.vector.matrix.android.internal.session.room.state.DefaultSendStateTask
|
||||
import im.vector.matrix.android.internal.session.room.state.SendStateTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
|
||||
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
|
||||
import im.vector.matrix.android.internal.session.room.timeline.*
|
||||
import org.koin.dsl.module.module
|
||||
import retrofit2.Retrofit
|
||||
|
||||
@ -67,11 +73,11 @@ class RoomModule {
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
LocalEchoEventFactory(get())
|
||||
LocalEchoEventFactory(get(), get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
RoomFactory(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
@ -82,9 +88,33 @@ class RoomModule {
|
||||
DefaultInviteTask(get()) as InviteTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultJoinRoomTask(get()) as JoinRoomTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultLeaveRoomTask(get()) as LeaveRoomTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultSendStateTask(get()) as SendStateTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultFindReactionEventForUndoTask(get()) as FindReactionEventForUndoTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultUpdateQuickReactionTask(get()) as UpdateQuickReactionTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultPruneEventTask(get()) as PruneEventTask
|
||||
}
|
||||
|
||||
scope(DefaultSession.SCOPE) {
|
||||
DefaultEventRelationsAggregationTask(get()) as EventRelationsAggregationTask
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package im.vector.matrix.android.internal.session.room
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
@ -28,8 +29,8 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.latestEvent
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.members.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary
|
||||
import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications
|
||||
import io.realm.Realm
|
||||
@ -41,11 +42,12 @@ internal class RoomSummaryUpdater(private val credentials: Credentials,
|
||||
|
||||
fun update(realm: Realm,
|
||||
roomId: String,
|
||||
membership: Membership? = null,
|
||||
roomSummary: RoomSyncSummary? = null,
|
||||
unreadNotifications: RoomSyncUnreadNotifications? = null) {
|
||||
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
?: realm.createObject(roomId)
|
||||
|
||||
if (roomSummary != null) {
|
||||
if (roomSummary.heroes.isNotEmpty()) {
|
||||
@ -65,8 +67,11 @@ internal class RoomSummaryUpdater(private val credentials: Credentials,
|
||||
if (unreadNotifications?.notificationCount != null) {
|
||||
roomSummaryEntity.notificationCount = unreadNotifications.notificationCount
|
||||
}
|
||||
if (membership != null) {
|
||||
roomSummaryEntity.membership = membership
|
||||
}
|
||||
|
||||
val lastEvent = EventEntity.latestEvent(realm, roomId, includedTypes = listOf(EventType.MESSAGE))
|
||||
val lastEvent = EventEntity.latestEvent(realm, roomId)
|
||||
val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain()
|
||||
val otherRoomMembers = RoomMembers(realm, roomId).getLoaded().filterKeys { it != credentials.userId }
|
||||
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString()
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.directory
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface GetPublicRoomTask : Task<GetPublicRoomTask.Params, PublicRoomsResponse> {
|
||||
data class Params(
|
||||
val server: String?,
|
||||
val publicRoomsParams: PublicRoomsParams
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultGetPublicRoomTask(private val roomAPI: RoomAPI) : GetPublicRoomTask {
|
||||
|
||||
override suspend fun execute(params: GetPublicRoomTask.Params): Try<PublicRoomsResponse> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.publicRooms(params.server, params.publicRoomsParams)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.directory
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface GetThirdPartyProtocolsTask : Task<Unit, Map<String, ThirdPartyProtocol>>
|
||||
|
||||
internal class DefaultGetThirdPartyProtocolsTask(private val roomAPI: RoomAPI) : GetThirdPartyProtocolsTask {
|
||||
|
||||
override suspend fun execute(params: Unit): Try<Map<String, ThirdPartyProtocol>> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.thirdPartyProtocols()
|
||||
}
|
||||
}
|
||||
}
|
@ -16,28 +16,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.members.RoomMembersService
|
||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.session.room.invite.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.util.fetchCopied
|
||||
|
||||
internal class DefaultRoomMembersService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : RoomMembersService {
|
||||
internal class DefaultMembershipService(private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val joinTask: JoinRoomTask,
|
||||
private val leaveRoomTask: LeaveRoomTask
|
||||
) : MembershipService {
|
||||
|
||||
override fun loadRoomMembersIfNeeded(): Cancelable {
|
||||
val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE)
|
||||
@ -68,4 +72,18 @@ internal class DefaultRoomMembersService(private val roomId: String,
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun join(callback: MatrixCallback<Unit>) {
|
||||
val params = JoinRoomTask.Params(roomId)
|
||||
joinTask.configureWith(params)
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
override fun leave(callback: MatrixCallback<Unit>) {
|
||||
val params = LeaveRoomTask.Params(roomId)
|
||||
leaveRoomTask.configureWith(params)
|
||||
.dispatchTo(callback)
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import arrow.core.Try
|
||||
import com.zhuinden.monarchy.Monarchy
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import android.content.Context
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
@ -22,7 +22,7 @@ import im.vector.matrix.android.R
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.MyMembership
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||
@ -77,24 +77,17 @@ internal class RoomDisplayNameResolver(private val context: Context,
|
||||
}
|
||||
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val otherRoomMembers = roomMembers.getLoaded()
|
||||
.filterKeys { it != credentials.userId }
|
||||
|
||||
if (roomEntity?.membership == MyMembership.INVITED) {
|
||||
//TODO handle invited
|
||||
/*
|
||||
if (currentUser != null
|
||||
&& !othersActiveMembers.isEmpty()
|
||||
&& !TextUtils.isEmpty(currentUser!!.mSender)) {
|
||||
// extract who invited us to the room
|
||||
name = context.getString(R.string.room_displayname_invite_from, roomState.resolve(currentUser!!.mSender))
|
||||
val loadedMembers = roomMembers.getLoaded()
|
||||
val otherRoomMembers = loadedMembers.filterKeys { it != credentials.userId }
|
||||
if (roomEntity?.membership == Membership.INVITE) {
|
||||
val inviteMeEvent = roomMembers.queryRoomMemberEvent(credentials.userId).findFirst()
|
||||
val inviterId = inviteMeEvent?.sender
|
||||
name = if (inviterId != null && otherRoomMembers.containsKey(inviterId)) {
|
||||
roomMemberDisplayNameResolver.resolve(inviterId, otherRoomMembers)
|
||||
} else {
|
||||
name = context.getString(R.string.room_displayname_room_invite)
|
||||
context.getString(R.string.room_displayname_room_invite)
|
||||
}
|
||||
*/
|
||||
name = context.getString(R.string.room_displayname_room_invite)
|
||||
} else {
|
||||
|
||||
val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
val memberIds = if (roomSummary?.heroes?.isNotEmpty() == true) {
|
||||
roomSummary.heroes
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.members
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
@ -5,7 +5,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.invite
|
||||
package im.vector.matrix.android.internal.session.room.membership.joining
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.invite
|
||||
package im.vector.matrix.android.internal.session.room.membership.joining
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.membership.joining
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface JoinRoomTask : Task<JoinRoomTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultJoinRoomTask(private val roomAPI: RoomAPI) : JoinRoomTask {
|
||||
|
||||
override suspend fun execute(params: JoinRoomTask.Params): Try<Unit> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.join(params.roomId, HashMap())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.membership.leaving
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
||||
internal interface LeaveRoomTask : Task<LeaveRoomTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultLeaveRoomTask(private val roomAPI: RoomAPI) : LeaveRoomTask {
|
||||
|
||||
override suspend fun execute(params: LeaveRoomTask.Params): Try<Unit> {
|
||||
return executeRequest {
|
||||
apiCall = roomAPI.leave(params.roomId, HashMap())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user