mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Merge pull request #2254 from vector-im/feature/bma/cleanup
Feature/bma/cleanup
This commit is contained in:
commit
cf98252bdb
287 changed files with 730 additions and 1081 deletions
|
@ -4,16 +4,7 @@
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
<value>
|
<value>
|
||||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
|
||||||
<value>
|
|
||||||
<package name="" alias="false" withSubpackages="true" />
|
|
||||||
<package name="java" alias="false" withSubpackages="true" />
|
|
||||||
<package name="javax" alias="false" withSubpackages="true" />
|
|
||||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
|
||||||
<package name="" alias="true" withSubpackages="true" />
|
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||||
|
|
|
@ -42,4 +42,4 @@ interface MatrixCallback<in T> {
|
||||||
/**
|
/**
|
||||||
* Basic no op implementation
|
* Basic no op implementation
|
||||||
*/
|
*/
|
||||||
class NoOpMatrixCallback<T>: MatrixCallback<T>
|
class NoOpMatrixCallback<T> : MatrixCallback<T>
|
||||||
|
|
|
@ -48,18 +48,25 @@ data class MatrixError(
|
||||||
companion object {
|
companion object {
|
||||||
/** Forbidden access, e.g. joining a room without permission, failed login. */
|
/** Forbidden access, e.g. joining a room without permission, failed login. */
|
||||||
const val M_FORBIDDEN = "M_FORBIDDEN"
|
const val M_FORBIDDEN = "M_FORBIDDEN"
|
||||||
|
|
||||||
/** An unknown error has occurred. */
|
/** An unknown error has occurred. */
|
||||||
const val M_UNKNOWN = "M_UNKNOWN"
|
const val M_UNKNOWN = "M_UNKNOWN"
|
||||||
|
|
||||||
/** The access token specified was not recognised. */
|
/** The access token specified was not recognised. */
|
||||||
const val M_UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN"
|
const val M_UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN"
|
||||||
|
|
||||||
/** No access token was specified for the request. */
|
/** No access token was specified for the request. */
|
||||||
const val M_MISSING_TOKEN = "M_MISSING_TOKEN"
|
const val M_MISSING_TOKEN = "M_MISSING_TOKEN"
|
||||||
|
|
||||||
/** Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys. */
|
/** Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys. */
|
||||||
const val M_BAD_JSON = "M_BAD_JSON"
|
const val M_BAD_JSON = "M_BAD_JSON"
|
||||||
|
|
||||||
/** Request did not contain valid JSON. */
|
/** Request did not contain valid JSON. */
|
||||||
const val M_NOT_JSON = "M_NOT_JSON"
|
const val M_NOT_JSON = "M_NOT_JSON"
|
||||||
|
|
||||||
/** No resource was found for this request. */
|
/** No resource was found for this request. */
|
||||||
const val M_NOT_FOUND = "M_NOT_FOUND"
|
const val M_NOT_FOUND = "M_NOT_FOUND"
|
||||||
|
|
||||||
/** Too many requests have been sent in a short period of time. Wait a while then try again. */
|
/** Too many requests have been sent in a short period of time. Wait a while then try again. */
|
||||||
const val M_LIMIT_EXCEEDED = "M_LIMIT_EXCEEDED"
|
const val M_LIMIT_EXCEEDED = "M_LIMIT_EXCEEDED"
|
||||||
|
|
||||||
|
@ -69,68 +76,97 @@ data class MatrixError(
|
||||||
|
|
||||||
/** Encountered when trying to register a user ID which has been taken. */
|
/** Encountered when trying to register a user ID which has been taken. */
|
||||||
const val M_USER_IN_USE = "M_USER_IN_USE"
|
const val M_USER_IN_USE = "M_USER_IN_USE"
|
||||||
|
|
||||||
/** Sent when the room alias given to the createRoom API is already in use. */
|
/** Sent when the room alias given to the createRoom API is already in use. */
|
||||||
const val M_ROOM_IN_USE = "M_ROOM_IN_USE"
|
const val M_ROOM_IN_USE = "M_ROOM_IN_USE"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_BAD_PAGINATION = "M_BAD_PAGINATION"
|
const val M_BAD_PAGINATION = "M_BAD_PAGINATION"
|
||||||
|
|
||||||
/** The request was not correctly authorized. Usually due to login failures. */
|
/** The request was not correctly authorized. Usually due to login failures. */
|
||||||
const val M_UNAUTHORIZED = "M_UNAUTHORIZED"
|
const val M_UNAUTHORIZED = "M_UNAUTHORIZED"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_OLD_VERSION = "M_OLD_VERSION"
|
const val M_OLD_VERSION = "M_OLD_VERSION"
|
||||||
|
|
||||||
/** The server did not understand the request. */
|
/** The server did not understand the request. */
|
||||||
const val M_UNRECOGNIZED = "M_UNRECOGNIZED"
|
const val M_UNRECOGNIZED = "M_UNRECOGNIZED"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_LOGIN_EMAIL_URL_NOT_YET = "M_LOGIN_EMAIL_URL_NOT_YET"
|
const val M_LOGIN_EMAIL_URL_NOT_YET = "M_LOGIN_EMAIL_URL_NOT_YET"
|
||||||
|
|
||||||
/** Authentication could not be performed on the third party identifier. */
|
/** Authentication could not be performed on the third party identifier. */
|
||||||
const val M_THREEPID_AUTH_FAILED = "M_THREEPID_AUTH_FAILED"
|
const val M_THREEPID_AUTH_FAILED = "M_THREEPID_AUTH_FAILED"
|
||||||
|
|
||||||
/** Sent when a threepid given to an API cannot be used because no record matching the threepid was found. */
|
/** Sent when a threepid given to an API cannot be used because no record matching the threepid was found. */
|
||||||
const val M_THREEPID_NOT_FOUND = "M_THREEPID_NOT_FOUND"
|
const val M_THREEPID_NOT_FOUND = "M_THREEPID_NOT_FOUND"
|
||||||
|
|
||||||
/** Sent when a threepid given to an API cannot be used because the same threepid is already in use. */
|
/** Sent when a threepid given to an API cannot be used because the same threepid is already in use. */
|
||||||
const val M_THREEPID_IN_USE = "M_THREEPID_IN_USE"
|
const val M_THREEPID_IN_USE = "M_THREEPID_IN_USE"
|
||||||
|
|
||||||
/** The client's request used a third party server, eg. identity server, that this server does not trust. */
|
/** The client's request used a third party server, eg. identity server, that this server does not trust. */
|
||||||
const val M_SERVER_NOT_TRUSTED = "M_SERVER_NOT_TRUSTED"
|
const val M_SERVER_NOT_TRUSTED = "M_SERVER_NOT_TRUSTED"
|
||||||
|
|
||||||
/** The request or entity was too large. */
|
/** The request or entity was too large. */
|
||||||
const val M_TOO_LARGE = "M_TOO_LARGE"
|
const val M_TOO_LARGE = "M_TOO_LARGE"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_CONSENT_NOT_GIVEN = "M_CONSENT_NOT_GIVEN"
|
const val M_CONSENT_NOT_GIVEN = "M_CONSENT_NOT_GIVEN"
|
||||||
|
|
||||||
/** The request cannot be completed because the homeserver has reached a resource limit imposed on it. For example,
|
/** The request cannot be completed because the homeserver has reached a resource limit imposed on it. For example,
|
||||||
* a homeserver held in a shared hosting environment may reach a resource limit if it starts using too much memory
|
* a homeserver held in a shared hosting environment may reach a resource limit if it starts using too much memory
|
||||||
* or disk space. The error MUST have an admin_contact field to provide the user receiving the error a place to reach
|
* or disk space. The error MUST have an admin_contact field to provide the user receiving the error a place to reach
|
||||||
* out to. Typically, this error will appear on routes which attempt to modify state (eg: sending messages, account
|
* out to. Typically, this error will appear on routes which attempt to modify state (eg: sending messages, account
|
||||||
* data, etc) and not routes which only read state (eg: /sync, get account data, etc). */
|
* data, etc) and not routes which only read state (eg: /sync, get account data, etc). */
|
||||||
const val M_RESOURCE_LIMIT_EXCEEDED = "M_RESOURCE_LIMIT_EXCEEDED"
|
const val M_RESOURCE_LIMIT_EXCEEDED = "M_RESOURCE_LIMIT_EXCEEDED"
|
||||||
|
|
||||||
/** The user ID associated with the request has been deactivated. Typically for endpoints that prove authentication, such as /login. */
|
/** The user ID associated with the request has been deactivated. Typically for endpoints that prove authentication, such as /login. */
|
||||||
const val M_USER_DEACTIVATED = "M_USER_DEACTIVATED"
|
const val M_USER_DEACTIVATED = "M_USER_DEACTIVATED"
|
||||||
|
|
||||||
/** Encountered when trying to register a user ID which is not valid. */
|
/** Encountered when trying to register a user ID which is not valid. */
|
||||||
const val M_INVALID_USERNAME = "M_INVALID_USERNAME"
|
const val M_INVALID_USERNAME = "M_INVALID_USERNAME"
|
||||||
|
|
||||||
/** Sent when the initial state given to the createRoom API is invalid. */
|
/** Sent when the initial state given to the createRoom API is invalid. */
|
||||||
const val M_INVALID_ROOM_STATE = "M_INVALID_ROOM_STATE"
|
const val M_INVALID_ROOM_STATE = "M_INVALID_ROOM_STATE"
|
||||||
|
|
||||||
/** The server does not permit this third party identifier. This may happen if the server only permits,
|
/** The server does not permit this third party identifier. This may happen if the server only permits,
|
||||||
* for example, email addresses from a particular domain. */
|
* for example, email addresses from a particular domain. */
|
||||||
const val M_THREEPID_DENIED = "M_THREEPID_DENIED"
|
const val M_THREEPID_DENIED = "M_THREEPID_DENIED"
|
||||||
|
|
||||||
/** The client's request to create a room used a room version that the server does not support. */
|
/** The client's request to create a room used a room version that the server does not support. */
|
||||||
const val M_UNSUPPORTED_ROOM_VERSION = "M_UNSUPPORTED_ROOM_VERSION"
|
const val M_UNSUPPORTED_ROOM_VERSION = "M_UNSUPPORTED_ROOM_VERSION"
|
||||||
|
|
||||||
/** The client attempted to join a room that has a version the server does not support.
|
/** The client attempted to join a room that has a version the server does not support.
|
||||||
* Inspect the room_version property of the error response for the room's version. */
|
* Inspect the room_version property of the error response for the room's version. */
|
||||||
const val M_INCOMPATIBLE_ROOM_VERSION = "M_INCOMPATIBLE_ROOM_VERSION"
|
const val M_INCOMPATIBLE_ROOM_VERSION = "M_INCOMPATIBLE_ROOM_VERSION"
|
||||||
|
|
||||||
/** The state change requested cannot be performed, such as attempting to unban a user who is not banned. */
|
/** The state change requested cannot be performed, such as attempting to unban a user who is not banned. */
|
||||||
const val M_BAD_STATE = "M_BAD_STATE"
|
const val M_BAD_STATE = "M_BAD_STATE"
|
||||||
|
|
||||||
/** The room or resource does not permit guests to access it. */
|
/** The room or resource does not permit guests to access it. */
|
||||||
const val M_GUEST_ACCESS_FORBIDDEN = "M_GUEST_ACCESS_FORBIDDEN"
|
const val M_GUEST_ACCESS_FORBIDDEN = "M_GUEST_ACCESS_FORBIDDEN"
|
||||||
|
|
||||||
/** A Captcha is required to complete the request. */
|
/** A Captcha is required to complete the request. */
|
||||||
const val M_CAPTCHA_NEEDED = "M_CAPTCHA_NEEDED"
|
const val M_CAPTCHA_NEEDED = "M_CAPTCHA_NEEDED"
|
||||||
|
|
||||||
/** The Captcha provided did not match what was expected. */
|
/** The Captcha provided did not match what was expected. */
|
||||||
const val M_CAPTCHA_INVALID = "M_CAPTCHA_INVALID"
|
const val M_CAPTCHA_INVALID = "M_CAPTCHA_INVALID"
|
||||||
|
|
||||||
/** A required parameter was missing from the request. */
|
/** A required parameter was missing from the request. */
|
||||||
const val M_MISSING_PARAM = "M_MISSING_PARAM"
|
const val M_MISSING_PARAM = "M_MISSING_PARAM"
|
||||||
|
|
||||||
/** A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string. */
|
/** A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string. */
|
||||||
const val M_INVALID_PARAM = "M_INVALID_PARAM"
|
const val M_INVALID_PARAM = "M_INVALID_PARAM"
|
||||||
|
|
||||||
/** The resource being requested is reserved by an application service, or the application service making the request has not created the resource. */
|
/** The resource being requested is reserved by an application service, or the application service making the request has not created the resource. */
|
||||||
const val M_EXCLUSIVE = "M_EXCLUSIVE"
|
const val M_EXCLUSIVE = "M_EXCLUSIVE"
|
||||||
|
|
||||||
/** The user is unable to reject an invite to join the server notices room. See the Server Notices module for more information. */
|
/** The user is unable to reject an invite to join the server notices room. See the Server Notices module for more information. */
|
||||||
const val M_CANNOT_LEAVE_SERVER_NOTICE_ROOM = "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM"
|
const val M_CANNOT_LEAVE_SERVER_NOTICE_ROOM = "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_WRONG_ROOM_KEYS_VERSION = "M_WRONG_ROOM_KEYS_VERSION"
|
const val M_WRONG_ROOM_KEYS_VERSION = "M_WRONG_ROOM_KEYS_VERSION"
|
||||||
|
|
||||||
/** (Not documented yet) */
|
/** (Not documented yet) */
|
||||||
const val M_WEAK_PASSWORD = "M_WEAK_PASSWORD"
|
const val M_WEAK_PASSWORD = "M_WEAK_PASSWORD"
|
||||||
|
|
||||||
|
|
|
@ -71,15 +71,15 @@ sealed class Action {
|
||||||
fun List<Action>.toJson(): List<Any> {
|
fun List<Action>.toJson(): List<Any> {
|
||||||
return map { action ->
|
return map { action ->
|
||||||
when (action) {
|
when (action) {
|
||||||
is Action.Notify -> Action.ACTION_NOTIFY
|
is Action.Notify -> Action.ACTION_NOTIFY
|
||||||
is Action.DoNotNotify -> Action.ACTION_DONT_NOTIFY
|
is Action.DoNotNotify -> Action.ACTION_DONT_NOTIFY
|
||||||
is Action.Sound -> {
|
is Action.Sound -> {
|
||||||
mapOf(
|
mapOf(
|
||||||
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
|
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
|
||||||
Action.ACTION_OBJECT_VALUE_KEY to action.sound
|
Action.ACTION_OBJECT_VALUE_KEY to action.sound
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Action.Highlight -> {
|
is Action.Highlight -> {
|
||||||
mapOf(
|
mapOf(
|
||||||
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
|
Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
|
||||||
Action.ACTION_OBJECT_VALUE_KEY to action.highlight
|
Action.ACTION_OBJECT_VALUE_KEY to action.highlight
|
||||||
|
@ -94,9 +94,9 @@ fun PushRule.getActions(): List<Action> {
|
||||||
|
|
||||||
actions.forEach { actionStrOrObj ->
|
actions.forEach { actionStrOrObj ->
|
||||||
when (actionStrOrObj) {
|
when (actionStrOrObj) {
|
||||||
Action.ACTION_NOTIFY -> Action.Notify
|
Action.ACTION_NOTIFY -> Action.Notify
|
||||||
Action.ACTION_DONT_NOTIFY -> Action.DoNotNotify
|
Action.ACTION_DONT_NOTIFY -> Action.DoNotNotify
|
||||||
is Map<*, *> -> {
|
is Map<*, *> -> {
|
||||||
when (actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]) {
|
when (actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]) {
|
||||||
Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> {
|
Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> {
|
||||||
(actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue ->
|
(actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue ->
|
||||||
|
@ -112,13 +112,13 @@ fun PushRule.getActions(): List<Action> {
|
||||||
// When the value is not there, default is true, says the spec
|
// When the value is not there, default is true, says the spec
|
||||||
?: Action.Highlight(true)
|
?: Action.Highlight(true)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Unsupported set_tweak value ${actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]}")
|
Timber.w("Unsupported set_tweak value ${actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]}")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Unsupported action type $actionStrOrObj")
|
Timber.w("Unsupported action type $actionStrOrObj")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@ package org.matrix.android.sdk.api.raw
|
||||||
|
|
||||||
sealed class RawCacheStrategy {
|
sealed class RawCacheStrategy {
|
||||||
// Data is always fetched from the server
|
// Data is always fetched from the server
|
||||||
object NoCache: RawCacheStrategy()
|
object NoCache : RawCacheStrategy()
|
||||||
|
|
||||||
// Once data is retrieved, it is stored for the provided amount of time.
|
// Once data is retrieved, it is stored for the provided amount of time.
|
||||||
// In case of error, and if strict is set to false, the cache can be returned if available
|
// In case of error, and if strict is set to false, the cache can be returned if available
|
||||||
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean): RawCacheStrategy()
|
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : RawCacheStrategy()
|
||||||
|
|
||||||
// Once retrieved, the data is stored in cache and will be always get from the cache
|
// Once retrieved, the data is stored in cache and will be always get from the cache
|
||||||
object InfiniteCache: RawCacheStrategy()
|
object InfiniteCache : RawCacheStrategy()
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ interface CallSignalingService {
|
||||||
|
|
||||||
fun removeCallListener(listener: CallsListener)
|
fun removeCallListener(listener: CallsListener)
|
||||||
|
|
||||||
fun getCallWithId(callId: String) : MxCall?
|
fun getCallWithId(callId: String): MxCall?
|
||||||
|
|
||||||
fun isThereAnyActiveCall(): Boolean
|
fun isThereAnyActiveCall(): Boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ interface MxCallDetail {
|
||||||
interface MxCall : MxCallDetail {
|
interface MxCall : MxCallDetail {
|
||||||
|
|
||||||
var state: CallState
|
var state: CallState
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick Up the incoming call
|
* Pick Up the incoming call
|
||||||
* It has no effect on outgoing call
|
* It has no effect on outgoing call
|
||||||
|
|
|
@ -101,9 +101,9 @@ interface CryptoService {
|
||||||
|
|
||||||
fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>)
|
fun fetchDevicesList(callback: MatrixCallback<DevicesListResponse>)
|
||||||
|
|
||||||
fun getMyDevicesInfo() : List<DeviceInfo>
|
fun getMyDevicesInfo(): List<DeviceInfo>
|
||||||
|
|
||||||
fun getLiveMyDevicesInfo() : LiveData<List<DeviceInfo>>
|
fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>>
|
||||||
|
|
||||||
fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
|
fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
|
||||||
|
|
||||||
|
@ -148,6 +148,6 @@ interface CryptoService {
|
||||||
fun getGossipingEventsTrail(): List<Event>
|
fun getGossipingEventsTrail(): List<Event>
|
||||||
|
|
||||||
// For testing shared session
|
// For testing shared session
|
||||||
fun getSharedWithInfo(roomId: String?, sessionId: String) : MXUsersDevicesMap<Int>
|
fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap<Int>
|
||||||
fun getWithHeldMegolmSession(roomId: String, sessionId: String) : RoomKeyWithHeldContent?
|
fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent?
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ interface KeysBackupService {
|
||||||
|
|
||||||
// For gossiping
|
// For gossiping
|
||||||
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
|
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
|
||||||
fun getKeyBackupRecoveryKeyInfo() : SavedKeyBackupKeyInfo?
|
fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo?
|
||||||
|
|
||||||
fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback<Boolean>)
|
fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback<Boolean>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,23 +53,31 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup
|
||||||
enum class KeysBackupState {
|
enum class KeysBackupState {
|
||||||
// Need to check the current backup version on the homeserver
|
// Need to check the current backup version on the homeserver
|
||||||
Unknown,
|
Unknown,
|
||||||
|
|
||||||
// Checking if backup is enabled on home server
|
// Checking if backup is enabled on home server
|
||||||
CheckingBackUpOnHomeserver,
|
CheckingBackUpOnHomeserver,
|
||||||
|
|
||||||
// Backup has been stopped because a new backup version has been detected on the homeserver
|
// Backup has been stopped because a new backup version has been detected on the homeserver
|
||||||
WrongBackUpVersion,
|
WrongBackUpVersion,
|
||||||
|
|
||||||
// Backup from this device is not enabled
|
// Backup from this device is not enabled
|
||||||
Disabled,
|
Disabled,
|
||||||
|
|
||||||
// There is a backup available on the homeserver but it is not trusted.
|
// There is a backup available on the homeserver but it is not trusted.
|
||||||
// It is not trusted because the signature is invalid or the device that created it is not verified
|
// It is not trusted because the signature is invalid or the device that created it is not verified
|
||||||
// Use [KeysBackup.getKeysBackupTrust()] to get trust details.
|
// Use [KeysBackup.getKeysBackupTrust()] to get trust details.
|
||||||
// Consequently, the backup from this device is not enabled.
|
// Consequently, the backup from this device is not enabled.
|
||||||
NotTrusted,
|
NotTrusted,
|
||||||
|
|
||||||
// Backup is being enabled: the backup version is being created on the homeserver
|
// Backup is being enabled: the backup version is being created on the homeserver
|
||||||
Enabling,
|
Enabling,
|
||||||
|
|
||||||
// Backup is enabled and ready to send backup to the homeserver
|
// Backup is enabled and ready to send backup to the homeserver
|
||||||
ReadyToBackUp,
|
ReadyToBackUp,
|
||||||
|
|
||||||
// e2e keys are going to be sent to the homeserver
|
// e2e keys are going to be sent to the homeserver
|
||||||
WillBackUp,
|
WillBackUp,
|
||||||
|
|
||||||
// e2e keys are being sent to the homeserver
|
// e2e keys are being sent to the homeserver
|
||||||
BackingUp
|
BackingUp
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ interface GossipingRequestListener {
|
||||||
* Returns the secret value to be shared
|
* Returns the secret value to be shared
|
||||||
* @return true if is handled
|
* @return true if is handled
|
||||||
*/
|
*/
|
||||||
fun onSecretShareRequest(request: IncomingSecretShareRequest) : Boolean
|
fun onSecretShareRequest(request: IncomingSecretShareRequest): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A room key request cancellation has been received.
|
* A room key request cancellation has been received.
|
||||||
|
|
|
@ -22,8 +22,10 @@ package org.matrix.android.sdk.api.session.crypto.verification
|
||||||
enum class VerificationMethod {
|
enum class VerificationMethod {
|
||||||
// Use it when your application supports the SAS verification method
|
// Use it when your application supports the SAS verification method
|
||||||
SAS,
|
SAS,
|
||||||
|
|
||||||
// Use it if your application is able to display QR codes
|
// Use it if your application is able to display QR codes
|
||||||
QR_CODE_SHOW,
|
QR_CODE_SHOW,
|
||||||
|
|
||||||
// Use it if your application is able to scan QR codes
|
// Use it if your application is able to scan QR codes
|
||||||
QR_CODE_SCAN
|
QR_CODE_SCAN
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@ fun Event.isFileMessage(): Boolean {
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Event.isAttachmentMessage(): Boolean {
|
fun Event.isAttachmentMessage(): Boolean {
|
||||||
return getClearType() == EventType.MESSAGE
|
return getClearType() == EventType.MESSAGE
|
||||||
&& when (getClearContent()?.toModel<MessageContent>()?.msgType) {
|
&& when (getClearContent()?.toModel<MessageContent>()?.msgType) {
|
||||||
|
|
|
@ -21,10 +21,13 @@ package org.matrix.android.sdk.api.session.events.model
|
||||||
object RelationType {
|
object RelationType {
|
||||||
/** Lets you define an event which annotates an existing event.*/
|
/** Lets you define an event which annotates an existing event.*/
|
||||||
const val ANNOTATION = "m.annotation"
|
const val ANNOTATION = "m.annotation"
|
||||||
|
|
||||||
/** Lets you define an event which replaces an existing event.*/
|
/** Lets you define an event which replaces an existing event.*/
|
||||||
const val REPLACE = "m.replace"
|
const val REPLACE = "m.replace"
|
||||||
|
|
||||||
/** Lets you define an event which references an existing event.*/
|
/** Lets you define an event which references an existing event.*/
|
||||||
const val REFERENCE = "m.reference"
|
const val REFERENCE = "m.reference"
|
||||||
|
|
||||||
/** Lets you define an event which adds a response to an existing event.*/
|
/** Lets you define an event which adds a response to an existing event.*/
|
||||||
const val RESPONSE = "org.matrix.response"
|
const val RESPONSE = "org.matrix.response"
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
package org.matrix.android.sdk.api.session.events.model
|
package org.matrix.android.sdk.api.session.events.model
|
||||||
|
|
||||||
interface UnsignedRelationInfo {
|
interface UnsignedRelationInfo {
|
||||||
val limited : Boolean?
|
val limited: Boolean?
|
||||||
val count: Int?
|
val count: Int?
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,12 @@ data class IntegrationManagerConfig(
|
||||||
* Defined in UserAccountData
|
* Defined in UserAccountData
|
||||||
*/
|
*/
|
||||||
ACCOUNT,
|
ACCOUNT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defined in Wellknown
|
* Defined in Wellknown
|
||||||
*/
|
*/
|
||||||
HOMESERVER,
|
HOMESERVER,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback value, hardcoded by the SDK
|
* Fallback value, hardcoded by the SDK
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.api.session.room.members
|
package org.matrix.android.sdk.api.session.room.members
|
||||||
|
|
||||||
sealed class ChangeMembershipState() {
|
sealed class ChangeMembershipState {
|
||||||
object Unknown : ChangeMembershipState()
|
object Unknown : ChangeMembershipState()
|
||||||
object Joining : ChangeMembershipState()
|
object Joining : ChangeMembershipState()
|
||||||
data class FailedJoining(val throwable: Throwable) : ChangeMembershipState()
|
data class FailedJoining(val throwable: Throwable) : ChangeMembershipState()
|
||||||
|
|
|
@ -35,7 +35,7 @@ data class PollSummaryContent(
|
||||||
return votes?.size ?: 0
|
return votes?.size ?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun voteCountForOption(optionIndex: Int) : Int {
|
fun voteCountForOption(optionIndex: Int): Int {
|
||||||
return votes?.filter { it.optionIndex == optionIndex }?.count() ?: 0
|
return votes?.filter { it.optionIndex == optionIndex }?.count() ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ data class RoomGuestAccessContent(
|
||||||
enum class GuestAccess(val value: String) {
|
enum class GuestAccess(val value: String) {
|
||||||
@Json(name = "can_join")
|
@Json(name = "can_join")
|
||||||
CanJoin("can_join"),
|
CanJoin("can_join"),
|
||||||
|
|
||||||
@Json(name = "forbidden")
|
@Json(name = "forbidden")
|
||||||
Forbidden("forbidden")
|
Forbidden("forbidden")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,19 @@ enum class RoomHistoryVisibility {
|
||||||
* participating homeserver with anyone, regardless of whether they have ever joined the room.
|
* participating homeserver with anyone, regardless of whether they have ever joined the room.
|
||||||
*/
|
*/
|
||||||
@Json(name = "world_readable") WORLD_READABLE,
|
@Json(name = "world_readable") WORLD_READABLE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Previous events are always accessible to newly joined members. All events in the
|
* Previous events are always accessible to newly joined members. All events in the
|
||||||
* room are accessible, even those sent when the member was not a part of the room.
|
* room are accessible, even those sent when the member was not a part of the room.
|
||||||
*/
|
*/
|
||||||
@Json(name = "shared") SHARED,
|
@Json(name = "shared") SHARED,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Events are accessible to newly joined members from the point they were invited onwards.
|
* Events are accessible to newly joined members from the point they were invited onwards.
|
||||||
* Events stop being accessible when the member's state changes to something other than invite or join.
|
* Events stop being accessible when the member's state changes to something other than invite or join.
|
||||||
*/
|
*/
|
||||||
@Json(name = "invited") INVITED,
|
@Json(name = "invited") INVITED,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Events are accessible to newly joined members from the point they joined the room onwards.
|
* Events are accessible to newly joined members from the point they joined the room onwards.
|
||||||
* Events stop being accessible when the member's state changes to something other than join.
|
* Events stop being accessible when the member's state changes to something other than join.
|
||||||
|
|
|
@ -53,6 +53,6 @@ data class MessageAudioContent(
|
||||||
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
) : MessageWithAttachmentContent {
|
) : MessageWithAttachmentContent {
|
||||||
|
|
||||||
override val mimeType: String?
|
override val mimeType: String?
|
||||||
get() = encryptedFileInfo?.mimetype ?: audioInfo?.mimeType
|
get() = encryptedFileInfo?.mimetype ?: audioInfo?.mimeType
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,6 @@ data class MessageImageContent(
|
||||||
*/
|
*/
|
||||||
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
) : MessageImageInfoContent {
|
) : MessageImageInfoContent {
|
||||||
override val mimeType: String?
|
override val mimeType: String?
|
||||||
get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: "image/*"
|
get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: "image/*"
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,6 @@ data class MessageStickerContent(
|
||||||
*/
|
*/
|
||||||
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
) : MessageImageInfoContent {
|
) : MessageImageInfoContent {
|
||||||
override val mimeType: String?
|
override val mimeType: String?
|
||||||
get() = encryptedFileInfo?.mimetype ?: info?.mimeType
|
get() = encryptedFileInfo?.mimetype ?: info?.mimeType
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ object MessageType {
|
||||||
const val MSGTYPE_RESPONSE = "org.matrix.response"
|
const val MSGTYPE_RESPONSE = "org.matrix.response"
|
||||||
const val MSGTYPE_POLL_CLOSED = "org.matrix.poll_closed"
|
const val MSGTYPE_POLL_CLOSED = "org.matrix.poll_closed"
|
||||||
const val MSGTYPE_VERIFICATION_REQUEST = "m.key.verification.request"
|
const val MSGTYPE_VERIFICATION_REQUEST = "m.key.verification.request"
|
||||||
|
|
||||||
// Add, in local, a fake message type in order to StickerMessage can inherit Message class
|
// 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
|
// Because sticker isn't a message type but a event type without msgtype field
|
||||||
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
|
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
|
||||||
|
|
|
@ -52,6 +52,6 @@ data class MessageVideoContent(
|
||||||
*/
|
*/
|
||||||
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
) : MessageWithAttachmentContent {
|
) : MessageWithAttachmentContent {
|
||||||
override val mimeType: String?
|
override val mimeType: String?
|
||||||
get() = encryptedFileInfo?.mimetype ?: videoInfo?.mimeType
|
get() = encryptedFileInfo?.mimetype ?: videoInfo?.mimeType
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,25 @@ package org.matrix.android.sdk.api.session.room.send
|
||||||
|
|
||||||
enum class SendState {
|
enum class SendState {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
|
|
||||||
// the event has not been sent
|
// the event has not been sent
|
||||||
UNSENT,
|
UNSENT,
|
||||||
|
|
||||||
// the event is encrypting
|
// the event is encrypting
|
||||||
ENCRYPTING,
|
ENCRYPTING,
|
||||||
|
|
||||||
// the event is currently sending
|
// the event is currently sending
|
||||||
SENDING,
|
SENDING,
|
||||||
|
|
||||||
// the event has been sent
|
// the event has been sent
|
||||||
SENT,
|
SENT,
|
||||||
|
|
||||||
// the event has been received from server
|
// the event has been received from server
|
||||||
SYNCED,
|
SYNCED,
|
||||||
|
|
||||||
// The event failed to be sent
|
// The event failed to be sent
|
||||||
UNDELIVERED,
|
UNDELIVERED,
|
||||||
|
|
||||||
// the event failed to be sent because some unknown devices have been found while encrypting it
|
// the event failed to be sent because some unknown devices have been found while encrypting it
|
||||||
FAILED_UNKNOWN_DEVICES;
|
FAILED_UNKNOWN_DEVICES;
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,7 @@ interface Timeline {
|
||||||
* It represents future events.
|
* It represents future events.
|
||||||
*/
|
*/
|
||||||
FORWARDS,
|
FORWARDS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It represents past events.
|
* It represents past events.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,5 +40,5 @@ interface TimelineService {
|
||||||
|
|
||||||
fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
|
fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
|
||||||
|
|
||||||
fun getAttachmentMessages() : List<TimelineEvent>
|
fun getAttachmentMessages(): List<TimelineEvent>
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ interface FilterService {
|
||||||
|
|
||||||
enum class FilterPreset {
|
enum class FilterPreset {
|
||||||
NoFilter,
|
NoFilter,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter for Riot, will include only known event type
|
* Filter for Riot, will include only known event type
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,7 +46,7 @@ data class Optional<T : Any> constructor(private val value: T?) {
|
||||||
return Optional(value)
|
return Optional(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T: Any> empty(): Optional<T> {
|
fun <T : Any> empty(): Optional<T> {
|
||||||
return Optional(null)
|
return Optional(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-
|
||||||
* Secured Shared Storage algorithm constant
|
* Secured Shared Storage algorithm constant
|
||||||
*/
|
*/
|
||||||
const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2"
|
const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2"
|
||||||
|
|
||||||
/* Secrets are encrypted using AES-CTR-256 and MACed using HMAC-SHA-256. **/
|
/* Secrets are encrypted using AES-CTR-256 and MACed using HMAC-SHA-256. **/
|
||||||
const val SSSS_ALGORITHM_AES_HMAC_SHA2 = "m.secret_storage.v1.aes-hmac-sha2"
|
const val SSSS_ALGORITHM_AES_HMAC_SHA2 = "m.secret_storage.v1.aes-hmac-sha2"
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ enum class GossipingRequestState {
|
||||||
ACCEPTING,
|
ACCEPTING,
|
||||||
ACCEPTED,
|
ACCEPTED,
|
||||||
FAILED_TO_ACCEPTED,
|
FAILED_TO_ACCEPTED,
|
||||||
// USER_REJECTED,
|
|
||||||
|
// USER_REJECTED,
|
||||||
UNABLE_TO_PROCESS,
|
UNABLE_TO_PROCESS,
|
||||||
CANCELLED_BY_REQUESTER,
|
CANCELLED_BY_REQUESTER,
|
||||||
RE_REQUESTED
|
RE_REQUESTED
|
||||||
|
|
|
@ -36,6 +36,7 @@ import kotlin.math.min
|
||||||
object MXMegolmExportEncryption {
|
object MXMegolmExportEncryption {
|
||||||
private const val HEADER_LINE = "-----BEGIN MEGOLM SESSION DATA-----"
|
private const val HEADER_LINE = "-----BEGIN MEGOLM SESSION DATA-----"
|
||||||
private const val TRAILER_LINE = "-----END MEGOLM SESSION DATA-----"
|
private const val TRAILER_LINE = "-----END MEGOLM SESSION DATA-----"
|
||||||
|
|
||||||
// we split into lines before base64ing, because encodeBase64 doesn't deal
|
// we split into lines before base64ing, because encodeBase64 doesn't deal
|
||||||
// terribly well with large arrays.
|
// terribly well with large arrays.
|
||||||
private const val LINE_LENGTH = 72 * 4 / 3
|
private const val LINE_LENGTH = 72 * 4 / 3
|
||||||
|
|
|
@ -70,7 +70,9 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
|
||||||
delay(1500)
|
delay(1500)
|
||||||
cryptoStore.getOrAddOutgoingSecretShareRequest(secretName, recipients)?.let {
|
cryptoStore.getOrAddOutgoingSecretShareRequest(secretName, recipients)?.let {
|
||||||
// TODO check if there is already one that is being sent?
|
// TODO check if there is already one that is being sent?
|
||||||
if (it.state == OutgoingGossipingRequestState.SENDING /**|| it.state == OutgoingGossipingRequestState.SENT*/) {
|
if (it.state == OutgoingGossipingRequestState.SENDING
|
||||||
|
/**|| it.state == OutgoingGossipingRequestState.SENT*/
|
||||||
|
) {
|
||||||
Timber.v("## CRYPTO - GOSSIP sendSecretShareRequest() : we are already sending for that session: $it")
|
Timber.v("## CRYPTO - GOSSIP sendSecretShareRequest() : we are already sending for that session: $it")
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ internal interface IMXDecrypting {
|
||||||
*/
|
*/
|
||||||
fun shareKeysWithDevice(request: IncomingRoomKeyRequest) {}
|
fun shareKeysWithDevice(request: IncomingRoomKeyRequest) {}
|
||||||
|
|
||||||
fun shareSecretWithDevice(request: IncomingSecretShareRequest, secretValue : String) {}
|
fun shareSecretWithDevice(request: IncomingSecretShareRequest, secretValue: String) {}
|
||||||
|
|
||||||
fun requestKeysForEvent(event: Event, withHeld: Boolean)
|
fun requestKeysForEvent(event: Event, withHeld: Boolean)
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||||
senderCurve25519Key = olmDecryptionResult.senderKey,
|
senderCurve25519Key = olmDecryptionResult.senderKey,
|
||||||
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
||||||
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||||
|
|
|
@ -43,7 +43,7 @@ internal class ShieldTrustUpdater @Inject constructor(
|
||||||
private val taskExecutor: TaskExecutor,
|
private val taskExecutor: TaskExecutor,
|
||||||
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
|
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
|
||||||
private val roomSummaryUpdater: RoomSummaryUpdater
|
private val roomSummaryUpdater: RoomSummaryUpdater
|
||||||
): SessionLifecycleObserver {
|
) : SessionLifecycleObserver {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
|
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
|
||||||
|
|
|
@ -80,6 +80,7 @@ class OlmInboundGroupSessionWrapper2 : Serializable {
|
||||||
constructor() {
|
constructor() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance from the provided keys map.
|
* Create a new instance from the provided keys map.
|
||||||
*
|
*
|
||||||
|
|
|
@ -66,19 +66,23 @@ enum class WithHeldCode(val value: String) {
|
||||||
* the user/device was blacklisted
|
* the user/device was blacklisted
|
||||||
*/
|
*/
|
||||||
BLACKLISTED("m.blacklisted"),
|
BLACKLISTED("m.blacklisted"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the user/devices is unverified
|
* the user/devices is unverified
|
||||||
*/
|
*/
|
||||||
UNVERIFIED("m.unverified"),
|
UNVERIFIED("m.unverified"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the user/device is not allowed have the key. For example, this would usually be sent in response
|
* the user/device is not allowed have the key. For example, this would usually be sent in response
|
||||||
* to a key request if the user was not in the room when the message was sent
|
* to a key request if the user was not in the room when the message was sent
|
||||||
*/
|
*/
|
||||||
UNAUTHORISED("m.unauthorised"),
|
UNAUTHORISED("m.unauthorised"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sent in reply to a key request if the device that the key is requested from does not have the requested key
|
* Sent in reply to a key request if the device that the key is requested from does not have the requested key
|
||||||
*/
|
*/
|
||||||
UNAVAILABLE("m.unavailable"),
|
UNAVAILABLE("m.unavailable"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An olm session could not be established.
|
* An olm session could not be established.
|
||||||
* This may happen, for example, if the sender was unable to obtain a one-time key from the recipient.
|
* This may happen, for example, if the sender was unable to obtain a one-time key from the recipient.
|
||||||
|
|
|
@ -17,6 +17,6 @@
|
||||||
package org.matrix.android.sdk.internal.crypto.store
|
package org.matrix.android.sdk.internal.crypto.store
|
||||||
|
|
||||||
data class SavedKeyBackupKeyInfo(
|
data class SavedKeyBackupKeyInfo(
|
||||||
val recoveryKey : String,
|
val recoveryKey: String,
|
||||||
val version: String
|
val version: String
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,10 +26,10 @@ internal fun OlmSessionEntity.Companion.createPrimaryKey(sessionId: String, devi
|
||||||
|
|
||||||
// olmSessionData is a serialized OlmSession
|
// olmSessionData is a serialized OlmSession
|
||||||
internal open class OlmSessionEntity(@PrimaryKey var primaryKey: String = "",
|
internal open class OlmSessionEntity(@PrimaryKey var primaryKey: String = "",
|
||||||
var sessionId: String? = null,
|
var sessionId: String? = null,
|
||||||
var deviceKey: String? = null,
|
var deviceKey: String? = null,
|
||||||
var olmSessionData: String? = null,
|
var olmSessionData: String? = null,
|
||||||
var lastReceivedMessageTs: Long = 0)
|
var lastReceivedMessageTs: Long = 0)
|
||||||
: RealmObject() {
|
: RealmObject() {
|
||||||
|
|
||||||
fun getOlmSession(): OlmSession? {
|
fun getOlmSession(): OlmSession? {
|
||||||
|
|
|
@ -138,7 +138,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||||
|
|
||||||
override fun onVerificationAccept(accept: ValidVerificationInfoAccept) {
|
override fun onVerificationAccept(accept: ValidVerificationInfoAccept) {
|
||||||
Timber.v("## SAS O: onVerificationAccept id:$transactionId")
|
Timber.v("## SAS O: onVerificationAccept id:$transactionId")
|
||||||
if (state != VerificationTxState.Started && state != VerificationTxState.SendingStart) {
|
if (state != VerificationTxState.Started && state != VerificationTxState.SendingStart) {
|
||||||
Timber.e("## SAS O: received accept request from invalid state $state")
|
Timber.e("## SAS O: received accept request from invalid state $state")
|
||||||
cancel(CancelCode.UnexpectedMessage)
|
cancel(CancelCode.UnexpectedMessage)
|
||||||
return
|
return
|
||||||
|
@ -212,7 +212,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||||
// - the Matrix ID of the user who sent the m.key.verification.accept message,
|
// - the Matrix ID of the user who sent the m.key.verification.accept message,
|
||||||
// - he device ID of the device that sent the m.key.verification.accept message
|
// - he device ID of the device that sent the m.key.verification.accept message
|
||||||
// - the transaction ID.
|
// - the transaction ID.
|
||||||
val sasInfo = "MATRIX_KEY_VERIFICATION_SAS$userId$deviceId$otherUserId$otherDeviceId$transactionId"
|
val sasInfo = "MATRIX_KEY_VERIFICATION_SAS$userId$deviceId$otherUserId$otherDeviceId$transactionId"
|
||||||
|
|
||||||
// decimal: generate five bytes by using HKDF.
|
// decimal: generate five bytes by using HKDF.
|
||||||
// emoji: generate six bytes by using HKDF.
|
// emoji: generate six bytes by using HKDF.
|
||||||
|
@ -220,7 +220,7 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
||||||
}
|
}
|
||||||
KEY_AGREEMENT_V2 -> {
|
KEY_AGREEMENT_V2 -> {
|
||||||
// Adds the SAS public key, and separate by |
|
// Adds the SAS public key, and separate by |
|
||||||
val sasInfo = "MATRIX_KEY_VERIFICATION_SAS|$userId|$deviceId|${getSAS().publicKey}|$otherUserId|$otherDeviceId|$otherKey|$transactionId"
|
val sasInfo = "MATRIX_KEY_VERIFICATION_SAS|$userId|$deviceId|${getSAS().publicKey}|$otherUserId|$otherDeviceId|$otherKey|$transactionId"
|
||||||
return getSAS().generateShortCode(sasInfo, 6)
|
return getSAS().generateShortCode(sasInfo, 6)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
|
@ -57,7 +57,7 @@ internal abstract class DefaultVerificationTransaction(
|
||||||
|
|
||||||
protected fun trust(canTrustOtherUserMasterKey: Boolean,
|
protected fun trust(canTrustOtherUserMasterKey: Boolean,
|
||||||
toVerifyDeviceIds: List<String>,
|
toVerifyDeviceIds: List<String>,
|
||||||
eventuallyMarkMyMasterKeyAsTrusted: Boolean, autoDone : Boolean = true) {
|
eventuallyMarkMyMasterKeyAsTrusted: Boolean, autoDone: Boolean = true) {
|
||||||
Timber.d("## Verification: trust ($otherUserId,$otherDeviceId) , verifiedDevices:$toVerifyDeviceIds")
|
Timber.d("## Verification: trust ($otherUserId,$otherDeviceId) , verifiedDevices:$toVerifyDeviceIds")
|
||||||
Timber.d("## Verification: trust Mark myMSK trusted $eventuallyMarkMyMasterKeyAsTrusted")
|
Timber.d("## Verification: trust Mark myMSK trusted $eventuallyMarkMyMasterKeyAsTrusted")
|
||||||
|
|
||||||
|
|
|
@ -68,10 +68,13 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||||
// Deprecated maybe removed later, use V2
|
// Deprecated maybe removed later, use V2
|
||||||
const val KEY_AGREEMENT_V1 = "curve25519"
|
const val KEY_AGREEMENT_V1 = "curve25519"
|
||||||
const val KEY_AGREEMENT_V2 = "curve25519-hkdf-sha256"
|
const val KEY_AGREEMENT_V2 = "curve25519-hkdf-sha256"
|
||||||
|
|
||||||
// ordered by preferred order
|
// ordered by preferred order
|
||||||
val KNOWN_AGREEMENT_PROTOCOLS = listOf(KEY_AGREEMENT_V2, KEY_AGREEMENT_V1)
|
val KNOWN_AGREEMENT_PROTOCOLS = listOf(KEY_AGREEMENT_V2, KEY_AGREEMENT_V1)
|
||||||
|
|
||||||
// ordered by preferred order
|
// ordered by preferred order
|
||||||
val KNOWN_HASHES = listOf("sha256")
|
val KNOWN_HASHES = listOf("sha256")
|
||||||
|
|
||||||
// ordered by preferred order
|
// ordered by preferred order
|
||||||
val KNOWN_MACS = listOf(SAS_MAC_SHA256, SAS_MAC_SHA256_LONGKDF)
|
val KNOWN_MACS = listOf(SAS_MAC_SHA256, SAS_MAC_SHA256_LONGKDF)
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ internal abstract class SASDefaultVerificationTransaction(
|
||||||
|
|
||||||
// Visible for test
|
// Visible for test
|
||||||
var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null
|
var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null
|
||||||
|
|
||||||
// Visible for test
|
// Visible for test
|
||||||
var accepted: ValidVerificationInfoAccept? = null
|
var accepted: ValidVerificationInfoAccept? = null
|
||||||
protected var otherKey: String? = null
|
protected var otherKey: String? = null
|
||||||
|
|
|
@ -118,7 +118,7 @@ internal class VerificationTransportRoomMessage(
|
||||||
?.firstOrNull { it.id == enqueueInfo.second }
|
?.firstOrNull { it.id == enqueueInfo.second }
|
||||||
?.let { wInfo ->
|
?.let { wInfo ->
|
||||||
when (wInfo.state) {
|
when (wInfo.state) {
|
||||||
WorkInfo.State.FAILED -> {
|
WorkInfo.State.FAILED -> {
|
||||||
tx?.cancel(onErrorReason)
|
tx?.cancel(onErrorReason)
|
||||||
workLiveData.removeObserver(this)
|
workLiveData.removeObserver(this)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ internal class VerificationTransportRoomMessage(
|
||||||
}
|
}
|
||||||
workLiveData.removeObserver(this)
|
workLiveData.removeObserver(this)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose to handle Realm migration to riotX
|
// Expose to handle Realm migration to riotX
|
||||||
fun getRealmEncryptionKey(alias: String) : ByteArray {
|
fun getRealmEncryptionKey(alias: String): ByteArray {
|
||||||
val key = if (hasKeyForDatabase(alias)) {
|
val key = if (hasKeyForDatabase(alias)) {
|
||||||
Timber.i("Found key for alias:$alias")
|
Timber.i("Found key for alias:$alias")
|
||||||
extractKeyForDatabase(alias)
|
extractKeyForDatabase(alias)
|
||||||
|
|
|
@ -28,8 +28,8 @@ import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
|
|
||||||
internal suspend fun <T> awaitNotEmptyResult(realmConfiguration: RealmConfiguration,
|
internal suspend fun <T> awaitNotEmptyResult(realmConfiguration: RealmConfiguration,
|
||||||
timeoutMillis: Long,
|
timeoutMillis: Long,
|
||||||
builder: (Realm) -> RealmQuery<T>) {
|
builder: (Realm) -> RealmQuery<T>) {
|
||||||
withTimeout(timeoutMillis) {
|
withTimeout(timeoutMillis) {
|
||||||
// Confine Realm interaction to a single thread with Looper.
|
// Confine Realm interaction to a single thread with Looper.
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
|
|
@ -23,12 +23,12 @@ import io.realm.annotations.Index
|
||||||
import io.realm.annotations.LinkingObjects
|
import io.realm.annotations.LinkingObjects
|
||||||
|
|
||||||
internal open class ChunkEntity(@Index var prevToken: String? = null,
|
internal open class ChunkEntity(@Index var prevToken: String? = null,
|
||||||
// Because of gaps we can have several chunks with nextToken == null
|
// Because of gaps we can have several chunks with nextToken == null
|
||||||
@Index var nextToken: String? = null,
|
@Index var nextToken: String? = null,
|
||||||
var stateEvents: RealmList<EventEntity> = RealmList(),
|
var stateEvents: RealmList<EventEntity> = RealmList(),
|
||||||
var timelineEvents: RealmList<TimelineEventEntity> = RealmList(),
|
var timelineEvents: RealmList<TimelineEventEntity> = RealmList(),
|
||||||
var numberOfTimelineEvents: Long = 0,
|
var numberOfTimelineEvents: Long = 0,
|
||||||
// Only one chunk will have isLastForward == true
|
// Only one chunk will have isLastForward == true
|
||||||
@Index var isLastForward: Boolean = false,
|
@Index var isLastForward: Boolean = false,
|
||||||
@Index var isLastBackward: Boolean = false
|
@Index var isLastBackward: Boolean = false
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
|
@ -20,5 +20,5 @@ import io.realm.RealmObject
|
||||||
import io.realm.annotations.PrimaryKey
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
internal open class SyncEntity(var nextBatch: String? = null,
|
internal open class SyncEntity(var nextBatch: String? = null,
|
||||||
@PrimaryKey var id: Long = 0
|
@PrimaryKey var id: Long = 0
|
||||||
) : RealmObject()
|
) : RealmObject()
|
||||||
|
|
|
@ -47,6 +47,7 @@ internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, roomId
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun EventAnnotationsSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity {
|
internal fun EventAnnotationsSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity {
|
||||||
return EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
return EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
||||||
?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId).apply { this.roomId = roomId }
|
?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId).apply { this.roomId = roomId }
|
||||||
|
|
|
@ -181,7 +181,7 @@ public class HomeServerConnectionConfig {
|
||||||
if (!TextUtils.isEmpty(jitsiServerUrl)) {
|
if (!TextUtils.isEmpty(jitsiServerUrl)) {
|
||||||
// add trailing "/"
|
// add trailing "/"
|
||||||
if (!jitsiServerUrl.endsWith("/")) {
|
if (!jitsiServerUrl.endsWith("/")) {
|
||||||
jitsiServerUrl =jitsiServerUrl + "/";
|
jitsiServerUrl = jitsiServerUrl + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.d("Overriding jitsi server url to " + jitsiServerUrl);
|
Timber.d("Overriding jitsi server url to " + jitsiServerUrl);
|
||||||
|
|
|
@ -20,6 +20,6 @@ package org.matrix.android.sdk.internal.legacy.riot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data class WellKnownManagerConfig(
|
data class WellKnownManagerConfig(
|
||||||
val apiUrl : String,
|
val apiUrl: String,
|
||||||
val uiUrl: String
|
val uiUrl: String
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,14 +22,14 @@ import retrofit2.Retrofit
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
|
|
||||||
object UnitConverterFactory : Converter.Factory() {
|
object UnitConverterFactory : Converter.Factory() {
|
||||||
override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>,
|
override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>,
|
||||||
retrofit: Retrofit): Converter<ResponseBody, *>? {
|
retrofit: Retrofit): Converter<ResponseBody, *>? {
|
||||||
return if (type == Unit::class.java) UnitConverter else null
|
return if (type == Unit::class.java) UnitConverter else null
|
||||||
}
|
}
|
||||||
|
|
||||||
private object UnitConverter : Converter<ResponseBody, Unit> {
|
private object UnitConverter : Converter<ResponseBody, Unit> {
|
||||||
override fun convert(value: ResponseBody) {
|
override fun convert(value: ResponseBody) {
|
||||||
value.close()
|
value.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ internal class DefaultGetUrlTask @Inject constructor(
|
||||||
|
|
||||||
override suspend fun execute(params: GetUrlTask.Params): String {
|
override suspend fun execute(params: GetUrlTask.Params): String {
|
||||||
return when (params.rawCacheStrategy) {
|
return when (params.rawCacheStrategy) {
|
||||||
RawCacheStrategy.NoCache -> doRequest(params.url)
|
RawCacheStrategy.NoCache -> doRequest(params.url)
|
||||||
is RawCacheStrategy.TtlCache -> doRequestWithCache(
|
is RawCacheStrategy.TtlCache -> doRequestWithCache(
|
||||||
params.url,
|
params.url,
|
||||||
params.rawCacheStrategy.validityDurationInMillis,
|
params.rawCacheStrategy.validityDurationInMillis,
|
||||||
params.rawCacheStrategy.strict
|
params.rawCacheStrategy.strict
|
||||||
|
|
|
@ -65,16 +65,16 @@ internal class ImageCompressor @Inject constructor() {
|
||||||
val orientation = exifInfo.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
|
val orientation = exifInfo.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
|
||||||
val matrix = Matrix()
|
val matrix = Matrix()
|
||||||
when (orientation) {
|
when (orientation) {
|
||||||
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
|
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
|
||||||
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
|
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
|
||||||
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
|
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
|
||||||
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.preScale(-1f, 1f)
|
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.preScale(-1f, 1f)
|
||||||
ExifInterface.ORIENTATION_FLIP_VERTICAL -> matrix.preScale(1f, -1f)
|
ExifInterface.ORIENTATION_FLIP_VERTICAL -> matrix.preScale(1f, -1f)
|
||||||
ExifInterface.ORIENTATION_TRANSPOSE -> {
|
ExifInterface.ORIENTATION_TRANSPOSE -> {
|
||||||
matrix.preRotate(-90f)
|
matrix.preRotate(-90f)
|
||||||
matrix.preScale(-1f, 1f)
|
matrix.preScale(-1f, 1f)
|
||||||
}
|
}
|
||||||
ExifInterface.ORIENTATION_TRANSVERSE -> {
|
ExifInterface.ORIENTATION_TRANSVERSE -> {
|
||||||
matrix.preRotate(90f)
|
matrix.preRotate(90f)
|
||||||
matrix.preScale(-1f, 1f)
|
matrix.preScale(-1f, 1f)
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
||||||
val updatedContent = when (messageContent) {
|
val updatedContent = when (messageContent) {
|
||||||
is MessageImageContent -> messageContent.update(url, encryptedFileInfo, newImageAttributes)
|
is MessageImageContent -> messageContent.update(url, encryptedFileInfo, newImageAttributes)
|
||||||
is MessageVideoContent -> messageContent.update(url, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
|
is MessageVideoContent -> messageContent.update(url, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
|
||||||
is MessageFileContent -> messageContent.update(url, encryptedFileInfo)
|
is MessageFileContent -> messageContent.update(url, encryptedFileInfo)
|
||||||
is MessageAudioContent -> messageContent.update(url, encryptedFileInfo)
|
is MessageAudioContent -> messageContent.update(url, encryptedFileInfo)
|
||||||
else -> messageContent
|
else -> messageContent
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ internal class DefaultAddThreePidTask @Inject constructor(
|
||||||
|
|
||||||
override suspend fun execute(params: Params) {
|
override suspend fun execute(params: Params) {
|
||||||
when (params.threePid) {
|
when (params.threePid) {
|
||||||
is ThreePid.Email -> addEmail(params.threePid)
|
is ThreePid.Email -> addEmail(params.threePid)
|
||||||
is ThreePid.Msisdn -> addMsisdn(params.threePid)
|
is ThreePid.Msisdn -> addMsisdn(params.threePid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,9 +108,9 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
}
|
}
|
||||||
val otherMembersCount = otherMembersSubset.count()
|
val otherMembersCount = otherMembersSubset.count()
|
||||||
name = when (otherMembersCount) {
|
name = when (otherMembersCount) {
|
||||||
0 -> stringProvider.getString(R.string.room_displayname_empty_room)
|
0 -> stringProvider.getString(R.string.room_displayname_empty_room)
|
||||||
1 -> resolveRoomMemberName(otherMembersSubset[0], roomMembers)
|
1 -> resolveRoomMemberName(otherMembersSubset[0], roomMembers)
|
||||||
2 -> stringProvider.getString(R.string.room_displayname_two_members,
|
2 -> stringProvider.getString(R.string.room_displayname_two_members,
|
||||||
resolveRoomMemberName(otherMembersSubset[0], roomMembers),
|
resolveRoomMemberName(otherMembersSubset[0], roomMembers),
|
||||||
resolveRoomMemberName(otherMembersSubset[1], roomMembers)
|
resolveRoomMemberName(otherMembersSubset[1], roomMembers)
|
||||||
)
|
)
|
||||||
|
|
|
@ -187,7 +187,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
||||||
localEchoRepository.updateSendState(localEcho.eventId, SendState.UNSENT)
|
localEchoRepository.updateSendState(localEcho.eventId, SendState.UNSENT)
|
||||||
internalSendMedia(listOf(localEcho.root), attachmentData, true)
|
internalSendMedia(listOf(localEcho.root), attachmentData, true)
|
||||||
}
|
}
|
||||||
is MessageFileContent -> {
|
is MessageFileContent -> {
|
||||||
val attachmentData = ContentAttachmentData(
|
val attachmentData = ContentAttachmentData(
|
||||||
size = messageContent.info!!.size,
|
size = messageContent.info!!.size,
|
||||||
mimeType = messageContent.info.mimeType!!,
|
mimeType = messageContent.info.mimeType!!,
|
||||||
|
|
|
@ -204,7 +204,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
ContentAttachmentData.Type.IMAGE -> createImageEvent(roomId, attachment)
|
ContentAttachmentData.Type.IMAGE -> createImageEvent(roomId, attachment)
|
||||||
ContentAttachmentData.Type.VIDEO -> createVideoEvent(roomId, attachment)
|
ContentAttachmentData.Type.VIDEO -> createVideoEvent(roomId, attachment)
|
||||||
ContentAttachmentData.Type.AUDIO -> createAudioEvent(roomId, attachment)
|
ContentAttachmentData.Type.AUDIO -> createAudioEvent(roomId, attachment)
|
||||||
ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment)
|
ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,8 @@ internal class MarkdownParser @Inject constructor(
|
||||||
return this
|
return this
|
||||||
// Remove extra space before and after the content
|
// Remove extra space before and after the content
|
||||||
.trim()
|
.trim()
|
||||||
// There is no need to include new line in an html-like source
|
// There is no need to include new line in an html-like source
|
||||||
// But new line can be in embedded code block, so do not remove them
|
// But new line can be in embedded code block, so do not remove them
|
||||||
// .replace("\n", "")
|
// .replace("\n", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,14 +423,14 @@ internal class DefaultTimeline(
|
||||||
|
|
||||||
private fun getState(direction: Timeline.Direction): State {
|
private fun getState(direction: Timeline.Direction): State {
|
||||||
return when (direction) {
|
return when (direction) {
|
||||||
Timeline.Direction.FORWARDS -> forwardsState.get()
|
Timeline.Direction.FORWARDS -> forwardsState.get()
|
||||||
Timeline.Direction.BACKWARDS -> backwardsState.get()
|
Timeline.Direction.BACKWARDS -> backwardsState.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateState(direction: Timeline.Direction, update: (State) -> State) {
|
private fun updateState(direction: Timeline.Direction, update: (State) -> State) {
|
||||||
val stateReference = when (direction) {
|
val stateReference = when (direction) {
|
||||||
Timeline.Direction.FORWARDS -> forwardsState
|
Timeline.Direction.FORWARDS -> forwardsState
|
||||||
Timeline.Direction.BACKWARDS -> backwardsState
|
Timeline.Direction.BACKWARDS -> backwardsState
|
||||||
}
|
}
|
||||||
val currentValue = stateReference.get()
|
val currentValue = stateReference.get()
|
||||||
|
@ -741,10 +741,10 @@ internal class DefaultTimeline(
|
||||||
return object : MatrixCallback<TokenChunkEventPersistor.Result> {
|
return object : MatrixCallback<TokenChunkEventPersistor.Result> {
|
||||||
override fun onSuccess(data: TokenChunkEventPersistor.Result) {
|
override fun onSuccess(data: TokenChunkEventPersistor.Result) {
|
||||||
when (data) {
|
when (data) {
|
||||||
TokenChunkEventPersistor.Result.SUCCESS -> {
|
TokenChunkEventPersistor.Result.SUCCESS -> {
|
||||||
Timber.v("Success fetching $limit items $direction from pagination request")
|
Timber.v("Success fetching $limit items $direction from pagination request")
|
||||||
}
|
}
|
||||||
TokenChunkEventPersistor.Result.REACHED_END -> {
|
TokenChunkEventPersistor.Result.REACHED_END -> {
|
||||||
postSnapshot()
|
postSnapshot()
|
||||||
}
|
}
|
||||||
TokenChunkEventPersistor.Result.SHOULD_FETCH_MORE ->
|
TokenChunkEventPersistor.Result.SHOULD_FETCH_MORE ->
|
||||||
|
|
|
@ -58,6 +58,7 @@ internal class TimelineEventDecryptor @Inject constructor(
|
||||||
|
|
||||||
// Set of eventIds which are currently decrypting
|
// Set of eventIds which are currently decrypting
|
||||||
private val existingRequests = mutableSetOf<DecryptionRequest>()
|
private val existingRequests = mutableSetOf<DecryptionRequest>()
|
||||||
|
|
||||||
// sessionId -> list of eventIds
|
// sessionId -> list of eventIds
|
||||||
private val unknownSessionsFailure = mutableMapOf<String, MutableSet<DecryptionRequest>>()
|
private val unknownSessionsFailure = mutableMapOf<String, MutableSet<DecryptionRequest>>()
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ internal class DefaultTypingService @AssistedInject constructor(
|
||||||
|
|
||||||
// What the homeserver knows
|
// What the homeserver knows
|
||||||
private var userIsTyping = false
|
private var userIsTyping = false
|
||||||
|
|
||||||
// Last time the user is typing event has been sent
|
// Last time the user is typing event has been sent
|
||||||
private var lastRequestTimestamp: Long = 0
|
private var lastRequestTimestamp: Long = 0
|
||||||
|
|
||||||
|
|
|
@ -91,9 +91,9 @@ internal class ReadReceiptHandler @Inject constructor() {
|
||||||
for ((eventId, receiptDict) in content) {
|
for ((eventId, receiptDict) in content) {
|
||||||
val userIdsDict = receiptDict[READ_KEY] ?: continue
|
val userIdsDict = receiptDict[READ_KEY] ?: continue
|
||||||
val readReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst()
|
val readReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst()
|
||||||
?: realm.createObject(ReadReceiptsSummaryEntity::class.java, eventId).apply {
|
?: realm.createObject(ReadReceiptsSummaryEntity::class.java, eventId).apply {
|
||||||
this.roomId = roomId
|
this.roomId = roomId
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((userId, paramsDict) in userIdsDict) {
|
for ((userId, paramsDict) in userIdsDict) {
|
||||||
val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0
|
val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0
|
||||||
|
|
|
@ -33,7 +33,7 @@ internal class RoomTagHandler @Inject constructor() {
|
||||||
RoomTagEntity(tagName, params["order"] as? Double)
|
RoomTagEntity(tagName, params["order"] as? Double)
|
||||||
}
|
}
|
||||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||||
?: RoomSummaryEntity(roomId)
|
?: RoomSummaryEntity(roomId)
|
||||||
|
|
||||||
roomSummaryEntity.tags.clear()
|
roomSummaryEntity.tags.clear()
|
||||||
roomSummaryEntity.tags.addAll(tags)
|
roomSummaryEntity.tags.addAll(tags)
|
||||||
|
|
|
@ -67,6 +67,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh
|
||||||
Timber.d("BRIDGE onWidgetEvent : $jsonEventData")
|
Timber.d("BRIDGE onWidgetEvent : $jsonEventData")
|
||||||
try {
|
try {
|
||||||
val dataAsDict = jsonAdapter.fromJson(jsonEventData)
|
val dataAsDict = jsonAdapter.fromJson(jsonEventData)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val eventData = (dataAsDict?.get("event.data") as? JsonDict) ?: return
|
val eventData = (dataAsDict?.get("event.data") as? JsonDict) ?: return
|
||||||
onWidgetMessage(eventData)
|
onWidgetMessage(eventData)
|
||||||
|
|
|
@ -92,7 +92,6 @@
|
||||||
<data android:host="element" />
|
<data android:host="element" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".features.media.ImageMediaViewerActivity" />
|
|
||||||
|
|
||||||
<!-- Add tools:ignore="Instantiatable" for the error reported only by Buildkite :/ -->
|
<!-- Add tools:ignore="Instantiatable" for the error reported only by Buildkite :/ -->
|
||||||
<activity
|
<activity
|
||||||
|
@ -108,7 +107,6 @@
|
||||||
android:name=".features.settings.VectorSettingsActivity"
|
android:name=".features.settings.VectorSettingsActivity"
|
||||||
android:label="@string/title_activity_settings"
|
android:label="@string/title_activity_settings"
|
||||||
android:windowSoftInputMode="adjustResize" />
|
android:windowSoftInputMode="adjustResize" />
|
||||||
<activity android:name=".features.media.VideoMediaViewerActivity" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".features.crypto.keysbackup.restore.KeysBackupRestoreActivity"
|
android:name=".features.crypto.keysbackup.restore.KeysBackupRestoreActivity"
|
||||||
android:label="@string/title_activity_keys_backup_setup" />
|
android:label="@string/title_activity_keys_backup_setup" />
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
package im.vector.app
|
package im.vector.app
|
||||||
|
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import im.vector.app.core.utils.BehaviorDataSource
|
import im.vector.app.core.utils.BehaviorDataSource
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,6 @@ import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleObserver
|
import androidx.lifecycle.LifecycleObserver
|
||||||
import androidx.lifecycle.OnLifecycleEvent
|
import androidx.lifecycle.OnLifecycleEvent
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import org.matrix.android.sdk.api.session.group.model.GroupSummary
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
|
||||||
import im.vector.app.features.grouplist.ALL_COMMUNITIES_GROUP_ID
|
import im.vector.app.features.grouplist.ALL_COMMUNITIES_GROUP_ID
|
||||||
import im.vector.app.features.grouplist.SelectedGroupDataSource
|
import im.vector.app.features.grouplist.SelectedGroupDataSource
|
||||||
import im.vector.app.features.home.HomeRoomListDataSource
|
import im.vector.app.features.home.HomeRoomListDataSource
|
||||||
|
@ -32,6 +29,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import io.reactivex.rxkotlin.addTo
|
import io.reactivex.rxkotlin.addTo
|
||||||
|
import org.matrix.android.sdk.api.session.group.model.GroupSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.rx.rx
|
import org.matrix.android.sdk.rx.rx
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
@ -23,7 +23,7 @@ import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class EmojiCompatFontProvider @Inject constructor(): FontsContractCompat.FontRequestCallback() {
|
class EmojiCompatFontProvider @Inject constructor() : FontsContractCompat.FontRequestCallback() {
|
||||||
|
|
||||||
var typeface: Typeface? = null
|
var typeface: Typeface? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class EmojiCompatWrapper @Inject constructor(private val context: Context) {
|
class EmojiCompatWrapper @Inject constructor(private val context: Context) {
|
||||||
|
|
||||||
private var initialized = false
|
private var initialized = false
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,7 @@ import im.vector.app.features.invite.VectorInviteView
|
||||||
import im.vector.app.features.link.LinkHandlerActivity
|
import im.vector.app.features.link.LinkHandlerActivity
|
||||||
import im.vector.app.features.login.LoginActivity
|
import im.vector.app.features.login.LoginActivity
|
||||||
import im.vector.app.features.media.BigImageViewerActivity
|
import im.vector.app.features.media.BigImageViewerActivity
|
||||||
import im.vector.app.features.media.ImageMediaViewerActivity
|
|
||||||
import im.vector.app.features.media.VectorAttachmentViewerActivity
|
import im.vector.app.features.media.VectorAttachmentViewerActivity
|
||||||
import im.vector.app.features.media.VideoMediaViewerActivity
|
|
||||||
import im.vector.app.features.navigation.Navigator
|
import im.vector.app.features.navigation.Navigator
|
||||||
import im.vector.app.features.permalink.PermalinkHandlerActivity
|
import im.vector.app.features.permalink.PermalinkHandlerActivity
|
||||||
import im.vector.app.features.pin.PinLocker
|
import im.vector.app.features.pin.PinLocker
|
||||||
|
@ -125,10 +123,8 @@ interface ScreenComponent {
|
||||||
fun inject(activity: MainActivity)
|
fun inject(activity: MainActivity)
|
||||||
fun inject(activity: RoomDirectoryActivity)
|
fun inject(activity: RoomDirectoryActivity)
|
||||||
fun inject(activity: BugReportActivity)
|
fun inject(activity: BugReportActivity)
|
||||||
fun inject(activity: ImageMediaViewerActivity)
|
|
||||||
fun inject(activity: FilteredRoomsActivity)
|
fun inject(activity: FilteredRoomsActivity)
|
||||||
fun inject(activity: CreateRoomActivity)
|
fun inject(activity: CreateRoomActivity)
|
||||||
fun inject(activity: VideoMediaViewerActivity)
|
|
||||||
fun inject(activity: CreateDirectRoomActivity)
|
fun inject(activity: CreateDirectRoomActivity)
|
||||||
fun inject(activity: IncomingShareActivity)
|
fun inject(activity: IncomingShareActivity)
|
||||||
fun inject(activity: SoftLogoutActivity)
|
fun inject(activity: SoftLogoutActivity)
|
||||||
|
|
|
@ -72,12 +72,12 @@ class UnrecognizedCertificateDialog @Inject constructor(
|
||||||
* @param callback callback to fire when the user makes a decision
|
* @param callback callback to fire when the user makes a decision
|
||||||
*/
|
*/
|
||||||
private fun internalShow(activity: Activity,
|
private fun internalShow(activity: Activity,
|
||||||
unrecognizedFingerprint: Fingerprint,
|
unrecognizedFingerprint: Fingerprint,
|
||||||
existing: Boolean,
|
existing: Boolean,
|
||||||
callback: Callback,
|
callback: Callback,
|
||||||
userId: String?,
|
userId: String?,
|
||||||
homeServerUrl: String,
|
homeServerUrl: String,
|
||||||
homeServerConnectionConfigHasFingerprints: Boolean) {
|
homeServerConnectionConfigHasFingerprints: Boolean) {
|
||||||
val dialogId = userId ?: homeServerUrl + unrecognizedFingerprint.displayableHexRepr
|
val dialogId = userId ?: homeServerUrl + unrecognizedFingerprint.displayableHexRepr
|
||||||
|
|
||||||
if (openDialogIds.contains(dialogId)) {
|
if (openDialogIds.contains(dialogId)) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ abstract class VectorEpoxyHolder : EpoxyHolder() {
|
||||||
protected fun <V : View> bind(id: Int): ReadOnlyProperty<VectorEpoxyHolder, V> =
|
protected fun <V : View> bind(id: Int): ReadOnlyProperty<VectorEpoxyHolder, V> =
|
||||||
Lazy { holder: VectorEpoxyHolder, prop ->
|
Lazy { holder: VectorEpoxyHolder, prop ->
|
||||||
holder.view.findViewById(id) as V?
|
holder.view.findViewById(id) as V?
|
||||||
?: throw IllegalStateException("View ID $id for '${prop.name}' not found.")
|
?: throw IllegalStateException("View ID $id for '${prop.name}' not found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,18 +42,25 @@ abstract class BottomSheetActionItem : VectorEpoxyModel<BottomSheetActionItem.Ho
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
var iconRes: Int = 0
|
var iconRes: Int = 0
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var textRes: Int = 0
|
var textRes: Int = 0
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var showExpand = false
|
var showExpand = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var expanded = false
|
var expanded = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var selected = false
|
var selected = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var subMenuItem = false
|
var subMenuItem = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var destructive = false
|
var destructive = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var listener: View.OnClickListener
|
lateinit var listener: View.OnClickListener
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,19 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var avatarRenderer: AvatarRenderer
|
lateinit var avatarRenderer: AvatarRenderer
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var matrixItem: MatrixItem
|
lateinit var matrixItem: MatrixItem
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var body: CharSequence
|
lateinit var body: CharSequence
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var time: CharSequence? = null
|
var time: CharSequence? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var movementMethod: MovementMethod? = null
|
var movementMethod: MovementMethod? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var userClicked: (() -> Unit)? = null
|
var userClicked: (() -> Unit)? = null
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,13 @@ abstract class BottomSheetQuickReactionsItem : VectorEpoxyModel<BottomSheetQuick
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var fontProvider: EmojiCompatFontProvider
|
lateinit var fontProvider: EmojiCompatFontProvider
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var texts: List<String>
|
lateinit var texts: List<String>
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var selecteds: List<Boolean>
|
lateinit var selecteds: List<Boolean>
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,10 @@ abstract class BottomSheetSendStateItem : VectorEpoxyModel<BottomSheetSendStateI
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var showProgress: Boolean = false
|
var showProgress: Boolean = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var text: CharSequence
|
lateinit var text: CharSequence
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
var drawableStart: Int = 0
|
var drawableStart: Int = 0
|
||||||
|
|
|
@ -30,6 +30,7 @@ abstract class BaseProfileMatrixItem<T : ProfileMatrixItem.Holder> : VectorEpoxy
|
||||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||||
@EpoxyAttribute var editable: Boolean = true
|
@EpoxyAttribute var editable: Boolean = true
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
||||||
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||||
|
|
|
@ -38,6 +38,7 @@ abstract class ProfileActionItem : VectorEpoxyModel<ProfileActionItem.Holder>()
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var title: String
|
lateinit var title: String
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var subtitle: String? = null
|
var subtitle: String? = null
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
|
|
||||||
@EpoxyModelClass(layout = R.layout.item_profile_section)
|
@EpoxyModelClass(layout = R.layout.item_profile_section)
|
||||||
abstract class ProfileSectionItem: VectorEpoxyModel<ProfileSectionItem.Holder>() {
|
abstract class ProfileSectionItem : VectorEpoxyModel<ProfileSectionItem.Holder>() {
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var title: String
|
lateinit var title: String
|
||||||
|
|
|
@ -55,46 +55,46 @@ class DefaultErrorFormatter @Inject constructor(
|
||||||
}
|
}
|
||||||
is Failure.ServerError -> {
|
is Failure.ServerError -> {
|
||||||
when {
|
when {
|
||||||
throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN -> {
|
throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN -> {
|
||||||
// Special case for terms and conditions
|
// Special case for terms and conditions
|
||||||
stringProvider.getString(R.string.error_terms_not_accepted)
|
stringProvider.getString(R.string.error_terms_not_accepted)
|
||||||
}
|
}
|
||||||
throwable.isInvalidPassword() -> {
|
throwable.isInvalidPassword() -> {
|
||||||
stringProvider.getString(R.string.auth_invalid_login_param)
|
stringProvider.getString(R.string.auth_invalid_login_param)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_USER_IN_USE -> {
|
throwable.error.code == MatrixError.M_USER_IN_USE -> {
|
||||||
stringProvider.getString(R.string.login_signup_error_user_in_use)
|
stringProvider.getString(R.string.login_signup_error_user_in_use)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_BAD_JSON -> {
|
throwable.error.code == MatrixError.M_BAD_JSON -> {
|
||||||
stringProvider.getString(R.string.login_error_bad_json)
|
stringProvider.getString(R.string.login_error_bad_json)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_NOT_JSON -> {
|
throwable.error.code == MatrixError.M_NOT_JSON -> {
|
||||||
stringProvider.getString(R.string.login_error_not_json)
|
stringProvider.getString(R.string.login_error_not_json)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_THREEPID_DENIED -> {
|
throwable.error.code == MatrixError.M_THREEPID_DENIED -> {
|
||||||
stringProvider.getString(R.string.login_error_threepid_denied)
|
stringProvider.getString(R.string.login_error_threepid_denied)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_LIMIT_EXCEEDED -> {
|
throwable.error.code == MatrixError.M_LIMIT_EXCEEDED -> {
|
||||||
limitExceededError(throwable.error)
|
limitExceededError(throwable.error)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_THREEPID_NOT_FOUND -> {
|
throwable.error.code == MatrixError.M_THREEPID_NOT_FOUND -> {
|
||||||
stringProvider.getString(R.string.login_reset_password_error_not_found)
|
stringProvider.getString(R.string.login_reset_password_error_not_found)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_USER_DEACTIVATED -> {
|
throwable.error.code == MatrixError.M_USER_DEACTIVATED -> {
|
||||||
stringProvider.getString(R.string.auth_invalid_login_deactivated_account)
|
stringProvider.getString(R.string.auth_invalid_login_deactivated_account)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_THREEPID_IN_USE
|
throwable.error.code == MatrixError.M_THREEPID_IN_USE
|
||||||
&& throwable.error.message == "Email is already in use" -> {
|
&& throwable.error.message == "Email is already in use" -> {
|
||||||
stringProvider.getString(R.string.account_email_already_used_error)
|
stringProvider.getString(R.string.account_email_already_used_error)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_THREEPID_IN_USE
|
throwable.error.code == MatrixError.M_THREEPID_IN_USE
|
||||||
&& throwable.error.message == "MSISDN is already in use" -> {
|
&& throwable.error.message == "MSISDN is already in use" -> {
|
||||||
stringProvider.getString(R.string.account_phone_number_already_used_error)
|
stringProvider.getString(R.string.account_phone_number_already_used_error)
|
||||||
}
|
}
|
||||||
throwable.error.code == MatrixError.M_THREEPID_AUTH_FAILED -> {
|
throwable.error.code == MatrixError.M_THREEPID_AUTH_FAILED -> {
|
||||||
stringProvider.getString(R.string.error_threepid_auth_failed)
|
stringProvider.getString(R.string.error_threepid_auth_failed)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throwable.error.message.takeIf { it.isNotEmpty() }
|
throwable.error.message.takeIf { it.isNotEmpty() }
|
||||||
?: throwable.error.code.takeIf { it.isNotEmpty() }
|
?: throwable.error.code.takeIf { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ import android.content.Context
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
|
||||||
import me.gujun.android.span.span
|
import me.gujun.android.span.span
|
||||||
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
|
||||||
class ResourceLimitErrorFormatter(private val context: Context) {
|
class ResourceLimitErrorFormatter(private val context: Context) {
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ fun addEntryToDownloadManager(context: Context,
|
||||||
file: File,
|
file: File,
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
title: String = file.name,
|
title: String = file.name,
|
||||||
description: String = file.name) : Uri? {
|
description: String = file.name): Uri? {
|
||||||
try {
|
try {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = ContentValues().apply {
|
||||||
|
@ -71,16 +71,16 @@ fun addEntryToDownloadManager(context: Context,
|
||||||
return context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
|
return context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
|
||||||
?.let { uri ->
|
?.let { uri ->
|
||||||
Timber.v("## addEntryToDownloadManager(): $uri")
|
Timber.v("## addEntryToDownloadManager(): $uri")
|
||||||
val source = file.inputStream().source().buffer()
|
val source = file.inputStream().source().buffer()
|
||||||
context.contentResolver.openOutputStream(uri)?.sink()?.buffer()?.let { sink ->
|
context.contentResolver.openOutputStream(uri)?.sink()?.buffer()?.let { sink ->
|
||||||
source.use { input ->
|
source.use { input ->
|
||||||
sink.use { output ->
|
sink.use { output ->
|
||||||
output.writeAll(input)
|
output.writeAll(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
uri
|
uri
|
||||||
} ?: run {
|
} ?: run {
|
||||||
Timber.v("## addEntryToDownloadManager(): context.contentResolver.insert failed")
|
Timber.v("## addEntryToDownloadManager(): context.contentResolver.insert failed")
|
||||||
|
|
||||||
null
|
null
|
||||||
|
|
|
@ -33,8 +33,6 @@ import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.lang.Exception
|
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
|
|
||||||
class VectorGlideModelLoaderFactory(private val activeSessionHolder: ActiveSessionHolder)
|
class VectorGlideModelLoaderFactory(private val activeSessionHolder: ActiveSessionHolder)
|
||||||
: ModelLoaderFactory<ImageContentRenderer.Data, InputStream> {
|
: ModelLoaderFactory<ImageContentRenderer.Data, InputStream> {
|
||||||
|
@ -118,7 +116,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde
|
||||||
url = data.url,
|
url = data.url,
|
||||||
fileName = data.filename,
|
fileName = data.filename,
|
||||||
elementToDecrypt = data.elementToDecrypt,
|
elementToDecrypt = data.elementToDecrypt,
|
||||||
callback = object: MatrixCallback<File> {
|
callback = object : MatrixCallback<File> {
|
||||||
override fun onSuccess(data: File) {
|
override fun onSuccess(data: File) {
|
||||||
callback.onDataReady(data.inputStream())
|
callback.onDataReady(data.inputStream())
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ fun analyseIntent(intent: Intent): List<ExternalIntentData> {
|
||||||
for (i in 0 until clipData.itemCount) {
|
for (i in 0 until clipData.itemCount) {
|
||||||
val item = clipData.getItemAt(i)
|
val item = clipData.getItemAt(i)
|
||||||
val mimeType = mimeTypes?.getOrElse(i) { mimeTypes[0] }
|
val mimeType = mimeTypes?.getOrElse(i) { mimeTypes[0] }
|
||||||
// uris list is not a valid mimetype
|
// uris list is not a valid mimetype
|
||||||
.takeUnless { it == ClipDescription.MIMETYPE_TEXT_URILIST }
|
.takeUnless { it == ClipDescription.MIMETYPE_TEXT_URILIST }
|
||||||
|
|
||||||
externalIntentDataList.add(ExternalIntentData.IntentDataClipData(item, mimeType))
|
externalIntentDataList.add(ExternalIntentData.IntentDataClipData(item, mimeType))
|
||||||
|
|
|
@ -121,7 +121,7 @@ object VectorLinkify {
|
||||||
remove = if (a.important) i + 1 else i
|
remove = if (a.important) i + 1 else i
|
||||||
} else {
|
} else {
|
||||||
when {
|
when {
|
||||||
b.end <= a.end ->
|
b.end <= a.end ->
|
||||||
// b is inside a -> b should be removed
|
// b is inside a -> b should be removed
|
||||||
remove = i + 1
|
remove = i + 1
|
||||||
a.end - a.start > b.end - b.start ->
|
a.end - a.start > b.end - b.start ->
|
||||||
|
|
|
@ -26,11 +26,11 @@ class CheckableFrameLayout : FrameLayout, Checkable {
|
||||||
|
|
||||||
private var mChecked = false
|
private var mChecked = false
|
||||||
|
|
||||||
constructor(context: Context) : super(context) {}
|
constructor(context: Context) : super(context)
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
override fun isChecked(): Boolean {
|
override fun isChecked(): Boolean {
|
||||||
return mChecked
|
return mChecked
|
||||||
|
|
|
@ -25,8 +25,8 @@ import butterknife.BindView
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ScreenComponent
|
import im.vector.app.core.di.ScreenComponent
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
import im.vector.app.core.extensions.hideKeyboard
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import kotlinx.android.synthetic.main.activity.*
|
import kotlinx.android.synthetic.main.activity.*
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -177,7 +177,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
Timber.i("onCreate Activity ${this.javaClass.simpleName}")
|
Timber.i("onCreate Activity ${javaClass.simpleName}")
|
||||||
val vectorComponent = getVectorComponent()
|
val vectorComponent = getVectorComponent()
|
||||||
screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this)
|
screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this)
|
||||||
val timeForInjection = measureTimeMillis {
|
val timeForInjection = measureTimeMillis {
|
||||||
|
@ -305,7 +305,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
Timber.i("onDestroy Activity ${this.javaClass.simpleName}")
|
Timber.i("onDestroy Activity ${javaClass.simpleName}")
|
||||||
unBinder?.unbind()
|
unBinder?.unbind()
|
||||||
unBinder = null
|
unBinder = null
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
Timber.i("onResume Activity ${this.javaClass.simpleName}")
|
Timber.i("onResume Activity ${javaClass.simpleName}")
|
||||||
|
|
||||||
configurationViewModel.onActivityResumed()
|
configurationViewModel.onActivityResumed()
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
Timber.i("onPause Activity ${this.javaClass.simpleName}")
|
Timber.i("onPause Activity ${javaClass.simpleName}")
|
||||||
|
|
||||||
rageShake.stop()
|
rageShake.stop()
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultListener : ResultListener? = null
|
var resultListener: ResultListener? = null
|
||||||
var bottomSheetResult: Int = ResultListener.RESULT_CANCEL
|
var bottomSheetResult: Int = ResultListener.RESULT_CANCEL
|
||||||
var bottomSheetResultData: Any? = null
|
var bottomSheetResultData: Any? = null
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment()
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
Timber.i("onResume BottomSheet ${this.javaClass.simpleName}")
|
Timber.i("onResume BottomSheet ${javaClass.simpleName}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
|
|
@ -58,7 +58,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
||||||
// Butterknife unbinder
|
// Butterknife unbinder
|
||||||
private var mUnBinder: Unbinder? = null
|
private var mUnBinder: Unbinder? = null
|
||||||
|
|
||||||
val vectorBaseActivity: VectorBaseActivity by lazy {
|
protected val vectorBaseActivity: VectorBaseActivity by lazy {
|
||||||
activity as VectorBaseActivity
|
activity as VectorBaseActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
Timber.i("onCreateView Fragment ${this.javaClass.simpleName}")
|
Timber.i("onCreateView Fragment ${javaClass.simpleName}")
|
||||||
return inflater.inflate(getLayoutResId(), container, false)
|
return inflater.inflate(getLayoutResId(), container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
||||||
@CallSuper
|
@CallSuper
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
Timber.i("onResume Fragment ${this.javaClass.simpleName}")
|
Timber.i("onResume Fragment ${javaClass.simpleName}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
|
@ -142,7 +142,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
||||||
@CallSuper
|
@CallSuper
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
Timber.i("onDestroyView Fragment ${this.javaClass.simpleName}")
|
Timber.i("onDestroyView Fragment ${javaClass.simpleName}")
|
||||||
mUnBinder?.unbind()
|
mUnBinder?.unbind()
|
||||||
mUnBinder = null
|
mUnBinder = null
|
||||||
uiDisposables.clear()
|
uiDisposables.clear()
|
||||||
|
|
|
@ -29,6 +29,7 @@ class DrawableProvider @Inject constructor(private val context: Context) {
|
||||||
fun getDrawable(@DrawableRes colorRes: Int): Drawable? {
|
fun getDrawable(@DrawableRes colorRes: Int): Drawable? {
|
||||||
return ContextCompat.getDrawable(context, colorRes)
|
return ContextCompat.getDrawable(context, colorRes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDrawable(@DrawableRes colorRes: Int, @ColorInt color: Int): Drawable? {
|
fun getDrawable(@DrawableRes colorRes: Int, @ColorInt color: Int): Drawable? {
|
||||||
return ContextCompat.getDrawable(context, colorRes)?.let {
|
return ContextCompat.getDrawable(context, colorRes)?.let {
|
||||||
ThemeUtils.tintDrawableWithColor(it, color)
|
ThemeUtils.tintDrawableWithColor(it, color)
|
||||||
|
|
|
@ -28,11 +28,11 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.error.ResourceLimitErrorFormatter
|
import im.vector.app.core.error.ResourceLimitErrorFormatter
|
||||||
import im.vector.app.core.utils.DimensionConverter
|
import im.vector.app.core.utils.DimensionConverter
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import kotlinx.android.synthetic.main.view_notification_area.view.*
|
import kotlinx.android.synthetic.main.view_notification_area.view.*
|
||||||
import me.gujun.android.span.span
|
import me.gujun.android.span.span
|
||||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
||||||
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,15 +56,19 @@ class PasswordStrengthBar @JvmOverloads constructor(
|
||||||
@BindColor(R.color.password_strength_bar_undefined)
|
@BindColor(R.color.password_strength_bar_undefined)
|
||||||
@JvmField
|
@JvmField
|
||||||
var colorBackground: Int = 0
|
var colorBackground: Int = 0
|
||||||
|
|
||||||
@BindColor(R.color.password_strength_bar_weak)
|
@BindColor(R.color.password_strength_bar_weak)
|
||||||
@JvmField
|
@JvmField
|
||||||
var colorWeak: Int = 0
|
var colorWeak: Int = 0
|
||||||
|
|
||||||
@BindColor(R.color.password_strength_bar_low)
|
@BindColor(R.color.password_strength_bar_low)
|
||||||
@JvmField
|
@JvmField
|
||||||
var colorLow: Int = 0
|
var colorLow: Int = 0
|
||||||
|
|
||||||
@BindColor(R.color.password_strength_bar_ok)
|
@BindColor(R.color.password_strength_bar_ok)
|
||||||
@JvmField
|
@JvmField
|
||||||
var colorOk: Int = 0
|
var colorOk: Int = 0
|
||||||
|
|
||||||
@BindColor(R.color.password_strength_bar_strong)
|
@BindColor(R.color.password_strength_bar_strong)
|
||||||
@JvmField
|
@JvmField
|
||||||
var colorStrong: Int = 0
|
var colorStrong: Int = 0
|
||||||
|
|
|
@ -40,13 +40,13 @@ import androidx.core.content.getSystemService
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import okio.source
|
import okio.source
|
||||||
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
|
|
|
@ -22,8 +22,6 @@ import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
|
||||||
import org.matrix.android.sdk.api.failure.GlobalError
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.di.ScreenComponent
|
import im.vector.app.core.di.ScreenComponent
|
||||||
|
@ -47,6 +45,8 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
|
import org.matrix.android.sdk.api.failure.GlobalError
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,10 @@ abstract class AttachmentPreviewItem<H : AttachmentPreviewItem.Holder> : VectorE
|
||||||
abstract class AttachmentMiniaturePreviewItem : AttachmentPreviewItem<AttachmentMiniaturePreviewItem.Holder>() {
|
abstract class AttachmentMiniaturePreviewItem : AttachmentPreviewItem<AttachmentMiniaturePreviewItem.Holder>() {
|
||||||
|
|
||||||
@EpoxyAttribute override lateinit var attachment: ContentAttachmentData
|
@EpoxyAttribute override lateinit var attachment: ContentAttachmentData
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var clickListener: View.OnClickListener? = null
|
var clickListener: View.OnClickListener? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var checked: Boolean = false
|
var checked: Boolean = false
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,6 @@ import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
|
||||||
sealed class AttachmentsPreviewAction : VectorViewModelAction {
|
sealed class AttachmentsPreviewAction : VectorViewModelAction {
|
||||||
object RemoveCurrentAttachment : AttachmentsPreviewAction()
|
object RemoveCurrentAttachment : AttachmentsPreviewAction()
|
||||||
data class SetCurrentAttachment(val index: Int): AttachmentsPreviewAction()
|
data class SetCurrentAttachment(val index: Int) : AttachmentsPreviewAction()
|
||||||
data class UpdatePathOfCurrentAttachment(val newUri: Uri): AttachmentsPreviewAction()
|
data class UpdatePathOfCurrentAttachment(val newUri: Uri) : AttachmentsPreviewAction()
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue