commit
9234c60155
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -67,4 +67,4 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
vector/build/outputs/apk/*/release/*.apk
|
vector/build/outputs/apk/*/release/*.apk
|
||||||
|
|
||||||
# TODO: add exodus checks
|
# TODO add exodus checks
|
||||||
|
20
.github/workflows/quality.yml
vendored
20
.github/workflows/quality.yml
vendored
@ -147,3 +147,23 @@ jobs:
|
|||||||
name: release-lint-report-${{ matrix.target }}
|
name: release-lint-report-${{ matrix.target }}
|
||||||
path: |
|
path: |
|
||||||
vector/build/reports/*.*
|
vector/build/reports/*.*
|
||||||
|
|
||||||
|
detekt:
|
||||||
|
name: Detekt Analysis
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Allow all jobs on main and develop. Just one per PR.
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.ref == 'refs/heads/main' && format('detekt-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('detekt-develop-{0}', github.sha) || format('detekt-{0}', github.ref) }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Run detekt
|
||||||
|
run: |
|
||||||
|
./gradlew detekt
|
||||||
|
- name: Upload reports
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: detekt-report
|
||||||
|
path: |
|
||||||
|
*/build/reports/detekt/detekt.html
|
||||||
|
16
build.gradle
16
build.gradle
@ -35,9 +35,11 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ktlint Plugin
|
|
||||||
plugins {
|
plugins {
|
||||||
|
// ktlint Plugin
|
||||||
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
|
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
|
||||||
|
// Detekt
|
||||||
|
id "io.gitlab.arturbosch.detekt" version "1.20.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/jeremylong/DependencyCheck
|
// https://github.com/jeremylong/DependencyCheck
|
||||||
@ -52,6 +54,7 @@ dependencyCheck {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||||
|
apply plugin: "io.gitlab.arturbosch.detekt"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Do not use `mavenCentral()`, it prevents Dependabot from working properly
|
// Do not use `mavenCentral()`, it prevents Dependabot from working properly
|
||||||
@ -119,7 +122,7 @@ allprojects {
|
|||||||
// display the corresponding rule
|
// display the corresponding rule
|
||||||
verbose = true
|
verbose = true
|
||||||
disabledRules = [
|
disabledRules = [
|
||||||
// TODO: Re-enable these 4 rules after reformatting project
|
// TODO Re-enable these 4 rules after reformatting project
|
||||||
"indent",
|
"indent",
|
||||||
"experimental:argument-list-wrapping",
|
"experimental:argument-list-wrapping",
|
||||||
"max-line-length",
|
"max-line-length",
|
||||||
@ -140,6 +143,15 @@ allprojects {
|
|||||||
"experimental:kdoc-wrapping",
|
"experimental:kdoc-wrapping",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detekt {
|
||||||
|
// preconfigure defaults
|
||||||
|
buildUponDefaultConfig = true
|
||||||
|
// activate all available (even unstable) rules.
|
||||||
|
allRules = true
|
||||||
|
// point to your custom config defining rules to run, overwriting default behavior
|
||||||
|
config = files("$rootDir/tools/detekt/detekt.yml")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
|
1
changelog.d/6038.misc
Normal file
1
changelog.d/6038.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Setup detekt
|
@ -123,6 +123,7 @@ ext.groups = [
|
|||||||
'io.github.detekt.sarif4k',
|
'io.github.detekt.sarif4k',
|
||||||
'io.github.microutils',
|
'io.github.microutils',
|
||||||
'io.github.reactivecircus.flowbinding',
|
'io.github.reactivecircus.flowbinding',
|
||||||
|
'io.gitlab.arturbosch.detekt',
|
||||||
'io.grpc',
|
'io.grpc',
|
||||||
'io.jsonwebtoken',
|
'io.jsonwebtoken',
|
||||||
'io.kindedj',
|
'io.kindedj',
|
||||||
@ -195,6 +196,7 @@ ext.groups = [
|
|||||||
'org.testng',
|
'org.testng',
|
||||||
'org.threeten',
|
'org.threeten',
|
||||||
'org.webjars',
|
'org.webjars',
|
||||||
|
'org.yaml',
|
||||||
'ru.noties',
|
'ru.noties',
|
||||||
'xerces',
|
'xerces',
|
||||||
'xml-apis',
|
'xml-apis',
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.lib.multipicker
|
package im.vector.lib.multipicker
|
||||||
|
|
||||||
class MultiPicker<T> {
|
class MultiPicker<T> private constructor() {
|
||||||
|
|
||||||
companion object Type {
|
companion object Type {
|
||||||
val IMAGE by lazy { MultiPicker<ImagePicker>() }
|
val IMAGE by lazy { MultiPicker<ImagePicker>() }
|
||||||
|
@ -22,15 +22,15 @@ package org.matrix.android.sdk.api.logger
|
|||||||
* val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
|
* val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
|
||||||
* Timber.tag(loggerTag.value).v("My log message")
|
* Timber.tag(loggerTag.value).v("My log message")
|
||||||
*/
|
*/
|
||||||
open class LoggerTag(_value: String, parentTag: LoggerTag? = null) {
|
open class LoggerTag(name: String, parentTag: LoggerTag? = null) {
|
||||||
|
|
||||||
object SYNC : LoggerTag("SYNC")
|
object SYNC : LoggerTag("SYNC")
|
||||||
object VOIP : LoggerTag("VOIP")
|
object VOIP : LoggerTag("VOIP")
|
||||||
object CRYPTO : LoggerTag("CRYPTO")
|
object CRYPTO : LoggerTag("CRYPTO")
|
||||||
|
|
||||||
val value: String = if (parentTag == null) {
|
val value: String = if (parentTag == null) {
|
||||||
_value
|
name
|
||||||
} else {
|
} else {
|
||||||
"${parentTag.value}/$_value"
|
"${parentTag.value}/$name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,13 @@ import timber.log.Timber
|
|||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class RoomGuestAccessContent(
|
data class RoomGuestAccessContent(
|
||||||
// Required. Whether guests can join the room. One of: ["can_join", "forbidden"]
|
// Required. Whether guests can join the room. One of: ["can_join", "forbidden"]
|
||||||
@Json(name = "guest_access") val _guestAccess: String? = null
|
@Json(name = "guest_access") val guestAccessStr: String? = null
|
||||||
) {
|
) {
|
||||||
val guestAccess: GuestAccess? = when (_guestAccess) {
|
val guestAccess: GuestAccess? = when (guestAccessStr) {
|
||||||
"can_join" -> GuestAccess.CanJoin
|
"can_join" -> GuestAccess.CanJoin
|
||||||
"forbidden" -> GuestAccess.Forbidden
|
"forbidden" -> GuestAccess.Forbidden
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Invalid value for GuestAccess: `$_guestAccess`")
|
Timber.w("Invalid value for GuestAccess: `$guestAccessStr`")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,15 @@ import timber.log.Timber
|
|||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class RoomHistoryVisibilityContent(
|
data class RoomHistoryVisibilityContent(
|
||||||
@Json(name = "history_visibility") val _historyVisibility: String? = null
|
@Json(name = "history_visibility") val historyVisibilityStr: String? = null
|
||||||
) {
|
) {
|
||||||
val historyVisibility: RoomHistoryVisibility? = when (_historyVisibility) {
|
val historyVisibility: RoomHistoryVisibility? = when (historyVisibilityStr) {
|
||||||
"world_readable" -> RoomHistoryVisibility.WORLD_READABLE
|
"world_readable" -> RoomHistoryVisibility.WORLD_READABLE
|
||||||
"shared" -> RoomHistoryVisibility.SHARED
|
"shared" -> RoomHistoryVisibility.SHARED
|
||||||
"invited" -> RoomHistoryVisibility.INVITED
|
"invited" -> RoomHistoryVisibility.INVITED
|
||||||
"joined" -> RoomHistoryVisibility.JOINED
|
"joined" -> RoomHistoryVisibility.JOINED
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Invalid value for RoomHistoryVisibility: `$_historyVisibility`")
|
Timber.w("Invalid value for RoomHistoryVisibility: `$historyVisibilityStr`")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import timber.log.Timber
|
|||||||
*/
|
*/
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class RoomJoinRulesContent(
|
data class RoomJoinRulesContent(
|
||||||
@Json(name = "join_rule") val _joinRules: String? = null,
|
@Json(name = "join_rule") val joinRulesStr: String? = null,
|
||||||
/**
|
/**
|
||||||
* If the allow key is an empty list (or not a list at all),
|
* If the allow key is an empty list (or not a list at all),
|
||||||
* then no users are allowed to join without an invite.
|
* then no users are allowed to join without an invite.
|
||||||
@ -35,14 +35,14 @@ data class RoomJoinRulesContent(
|
|||||||
*/
|
*/
|
||||||
@Json(name = "allow") val allowList: List<RoomJoinRulesAllowEntry>? = null
|
@Json(name = "allow") val allowList: List<RoomJoinRulesAllowEntry>? = null
|
||||||
) {
|
) {
|
||||||
val joinRules: RoomJoinRules? = when (_joinRules) {
|
val joinRules: RoomJoinRules? = when (joinRulesStr) {
|
||||||
"public" -> RoomJoinRules.PUBLIC
|
"public" -> RoomJoinRules.PUBLIC
|
||||||
"invite" -> RoomJoinRules.INVITE
|
"invite" -> RoomJoinRules.INVITE
|
||||||
"knock" -> RoomJoinRules.KNOCK
|
"knock" -> RoomJoinRules.KNOCK
|
||||||
"private" -> RoomJoinRules.PRIVATE
|
"private" -> RoomJoinRules.PRIVATE
|
||||||
"restricted" -> RoomJoinRules.RESTRICTED
|
"restricted" -> RoomJoinRules.RESTRICTED
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Invalid value for RoomJoinRules: `$_joinRules`")
|
Timber.w("Invalid value for RoomJoinRules: `$joinRulesStr`")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class RestrictedRoomPreset(val homeServerCapabilities: HomeServerCapabilities, v
|
|||||||
type = EventType.STATE_ROOM_JOIN_RULES,
|
type = EventType.STATE_ROOM_JOIN_RULES,
|
||||||
stateKey = "",
|
stateKey = "",
|
||||||
content = RoomJoinRulesContent(
|
content = RoomJoinRulesContent(
|
||||||
_joinRules = RoomJoinRules.RESTRICTED.value,
|
joinRulesStr = RoomJoinRules.RESTRICTED.value,
|
||||||
allowList = restrictedList
|
allowList = restrictedList
|
||||||
).toContent()
|
).toContent()
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,6 @@ import com.squareup.moshi.JsonClass
|
|||||||
|
|
||||||
@JsonClass(generateAdapter = false)
|
@JsonClass(generateAdapter = false)
|
||||||
sealed class LazyRoomSyncEphemeral {
|
sealed class LazyRoomSyncEphemeral {
|
||||||
data class Parsed(val _roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral()
|
data class Parsed(val roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral()
|
||||||
object Stored : LazyRoomSyncEphemeral()
|
object Stored : LazyRoomSyncEphemeral()
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ internal fun Versions.isLoginAndRegistrationSupportedBySdk(): Boolean {
|
|||||||
* Indicate if the homeserver support MSC3440 for threads
|
* Indicate if the homeserver support MSC3440 for threads
|
||||||
*/
|
*/
|
||||||
internal fun Versions.doesServerSupportThreads(): Boolean {
|
internal fun Versions.doesServerSupportThreads(): Boolean {
|
||||||
// TODO: Check for v1.3 or whichever spec version formally specifies MSC3440.
|
// TODO Check for v1.3 or whichever spec version formally specifies MSC3440.
|
||||||
return unstableFeatures?.get(FEATURE_THREADS_MSC3440_STABLE) ?: false
|
return unstableFeatures?.get(FEATURE_THREADS_MSC3440_STABLE) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ internal class PerSessionBackupQueryRateLimiter @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val MIN_TRY_BACKUP_PERIOD_MILLIS = 60 * 60_000 // 1 hour
|
const val MIN_TRY_BACKUP_PERIOD_MILLIS = 60 * 60_000 // 1 hour
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Info(
|
data class Info(
|
||||||
|
@ -79,7 +79,7 @@ internal class RoomDecryptorProvider @Inject constructor(
|
|||||||
newSessionListeners.toList().forEach {
|
newSessionListeners.toList().forEach {
|
||||||
try {
|
try {
|
||||||
it.onNewSession(roomId, senderKey, sessionId)
|
it.onNewSession(roomId, senderKey, sessionId)
|
||||||
} catch (e: Throwable) {
|
} catch (ignore: Throwable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ internal class MXMegolmEncryption(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default rotation periods
|
// Default rotation periods
|
||||||
// TODO: Make it configurable via parameters
|
// TODO Make it configurable via parameters
|
||||||
// Session rotation periods
|
// Session rotation periods
|
||||||
private var sessionRotationPeriodMsgs: Int = 100
|
private var sessionRotationPeriodMsgs: Int = 100
|
||||||
private var sessionRotationPeriodMs: Int = 7 * 24 * 3600 * 1000
|
private var sessionRotationPeriodMs: Int = 7 * 24 * 3600 * 1000
|
||||||
|
@ -38,7 +38,7 @@ internal class MXOlmEncryption(
|
|||||||
override suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List<String>): Content {
|
override suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List<String>): Content {
|
||||||
// pick the list of recipients based on the membership list.
|
// pick the list of recipients based on the membership list.
|
||||||
//
|
//
|
||||||
// TODO: there is a race condition here! What if a new user turns up
|
// TODO there is a race condition here! What if a new user turns up
|
||||||
ensureSession(userIds)
|
ensureSession(userIds)
|
||||||
val deviceInfos = ArrayList<CryptoDeviceInfo>()
|
val deviceInfos = ArrayList<CryptoDeviceInfo>()
|
||||||
for (userId in userIds) {
|
for (userId in userIds) {
|
||||||
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
|||||||
@SessionScope
|
@SessionScope
|
||||||
internal class WarnOnUnknownDeviceRepository @Inject constructor() {
|
internal class WarnOnUnknownDeviceRepository @Inject constructor() {
|
||||||
|
|
||||||
// TODO: set it back to true by default. Need UI
|
// TODO set it back to true by default. Need UI
|
||||||
// Warn the user if some new devices are detected while encrypting a message.
|
// Warn the user if some new devices are detected while encrypting a message.
|
||||||
private var warnOnUnknownDevices = false
|
private var warnOnUnknownDevices = false
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ internal class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7)
|
|||||||
val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures)
|
val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures)
|
||||||
it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures)
|
it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures)
|
||||||
}
|
}
|
||||||
} catch (failure: Throwable) {
|
} catch (ignore: Throwable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate frozen classes
|
// Migrate frozen classes
|
||||||
|
@ -69,6 +69,7 @@ internal class DefaultSendEventTask @Inject constructor(
|
|||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
// localEchoRepository.updateSendState(params.event.eventId!!, SendState.UNDELIVERED)
|
// localEchoRepository.updateSendState(params.event.eventId!!, SendState.UNDELIVERED)
|
||||||
|
Timber.w(e, "Unable to send the Event")
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.matrix.android.sdk.internal.crypto.tasks
|
package org.matrix.android.sdk.internal.crypto.tasks
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
|
||||||
import org.matrix.android.sdk.internal.crypto.api.CryptoApi
|
import org.matrix.android.sdk.internal.crypto.api.CryptoApi
|
||||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||||
import org.matrix.android.sdk.internal.network.executeRequest
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
@ -34,20 +33,15 @@ internal class DefaultUploadSignaturesTask @Inject constructor(
|
|||||||
) : UploadSignaturesTask {
|
) : UploadSignaturesTask {
|
||||||
|
|
||||||
override suspend fun execute(params: UploadSignaturesTask.Params) {
|
override suspend fun execute(params: UploadSignaturesTask.Params) {
|
||||||
try {
|
val response = executeRequest(
|
||||||
val response = executeRequest(
|
globalErrorReceiver,
|
||||||
globalErrorReceiver,
|
canRetry = true,
|
||||||
canRetry = true,
|
maxRetriesCount = 10
|
||||||
maxRetriesCount = 10
|
) {
|
||||||
) {
|
cryptoApi.uploadSignatures(params.signatures)
|
||||||
cryptoApi.uploadSignatures(params.signatures)
|
}
|
||||||
}
|
if (response.failures?.isNotEmpty() == true) {
|
||||||
if (response.failures?.isNotEmpty() == true) {
|
throw Throwable(response.failures.toString())
|
||||||
throw Throwable(response.failures.toString())
|
|
||||||
}
|
|
||||||
return
|
|
||||||
} catch (f: Failure) {
|
|
||||||
throw f
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ internal object CertUtil {
|
|||||||
builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions)
|
builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions)
|
||||||
val list = ArrayList<ConnectionSpec>()
|
val list = ArrayList<ConnectionSpec>()
|
||||||
list.add(builder.build())
|
list.add(builder.build())
|
||||||
// TODO: we should display a warning if user enter an http url
|
// TODO we should display a warning if user enter an http url
|
||||||
if (hsConfig.allowHttpExtension || hsConfig.homeServerUriBase.toString().startsWith("http://")) {
|
if (hsConfig.allowHttpExtension || hsConfig.homeServerUriBase.toString().startsWith("http://")) {
|
||||||
list.add(ConnectionSpec.CLEARTEXT)
|
list.add(ConnectionSpec.CLEARTEXT)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ internal class DefaultFileService @Inject constructor(
|
|||||||
|
|
||||||
Timber.v("## FileService downloadFile $url")
|
Timber.v("## FileService downloadFile $url")
|
||||||
|
|
||||||
// TODO: Remove use of `synchronized` in suspend function.
|
// TODO Remove use of `synchronized` in suspend function.
|
||||||
val existingDownload = synchronized(ongoing) {
|
val existingDownload = synchronized(ongoing) {
|
||||||
val existing = ongoing[url]
|
val existing = ongoing[url]
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
|
@ -29,6 +29,6 @@ internal data class GroupSummaryRoomsSection(
|
|||||||
|
|
||||||
@Json(name = "rooms") val rooms: List<String> = emptyList()
|
@Json(name = "rooms") val rooms: List<String> = emptyList()
|
||||||
|
|
||||||
// @TODO: Check the meaning and the usage of these categories. This dictionary is empty FTM.
|
// TODO Check the meaning and the usage of these categories. This dictionary is empty FTM.
|
||||||
// public Map<Object, Object> categories;
|
// public Map<Object, Object> categories;
|
||||||
)
|
)
|
||||||
|
@ -30,6 +30,6 @@ internal data class GroupSummaryUsersSection(
|
|||||||
|
|
||||||
@Json(name = "users") val users: List<String> = emptyList()
|
@Json(name = "users") val users: List<String> = emptyList()
|
||||||
|
|
||||||
// @TODO: Check the meaning and the usage of these roles. This dictionary is empty FTM.
|
// TODO Check the meaning and the usage of these roles. This dictionary is empty FTM.
|
||||||
// public Map<Object, Object> roles;
|
// public Map<Object, Object> roles;
|
||||||
)
|
)
|
||||||
|
@ -16,14 +16,16 @@
|
|||||||
|
|
||||||
package org.matrix.android.sdk.internal.session.identity.model
|
package org.matrix.android.sdk.internal.session.identity.model
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class SignInvitationBody(
|
internal data class SignInvitationBody(
|
||||||
/**The Matrix user ID of the user accepting the invitation.*/
|
/** The Matrix user ID of the user accepting the invitation.*/
|
||||||
val mxid: String,
|
val mxid: String,
|
||||||
/**The token from the call to store- invite..*/
|
/** The token from the call to store- invite..*/
|
||||||
val token: String,
|
val token: String,
|
||||||
/** The private key, encoded as Unpadded base64. */
|
/** The private key, encoded as Unpadded base64. */
|
||||||
val private_key: String
|
@Json(name = "private_key")
|
||||||
|
val privateKey: String
|
||||||
)
|
)
|
||||||
|
@ -136,7 +136,7 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
|
|||||||
if (joinRules != null) {
|
if (joinRules != null) {
|
||||||
val body = if (joinRules == RoomJoinRules.RESTRICTED) {
|
val body = if (joinRules == RoomJoinRules.RESTRICTED) {
|
||||||
RoomJoinRulesContent(
|
RoomJoinRulesContent(
|
||||||
_joinRules = RoomJoinRules.RESTRICTED.value,
|
joinRulesStr = RoomJoinRules.RESTRICTED.value,
|
||||||
allowList = allowList
|
allowList = allowList
|
||||||
).toContent()
|
).toContent()
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,8 +23,11 @@ import org.matrix.android.sdk.api.session.events.model.toModel
|
|||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializable object
|
||||||
|
*/
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class SerializablePowerLevelsContent(
|
internal data class SafePowerLevelContent(
|
||||||
@Json(name = "ban") val ban: Int?,
|
@Json(name = "ban") val ban: Int?,
|
||||||
@Json(name = "kick") val kick: Int?,
|
@Json(name = "kick") val kick: Int?,
|
||||||
@Json(name = "invite") val invite: Int?,
|
@Json(name = "invite") val invite: Int?,
|
||||||
@ -41,7 +44,7 @@ internal data class SerializablePowerLevelsContent(
|
|||||||
internal fun JsonDict.toSafePowerLevelsContentDict(): JsonDict {
|
internal fun JsonDict.toSafePowerLevelsContentDict(): JsonDict {
|
||||||
return toModel<PowerLevelsContent>()
|
return toModel<PowerLevelsContent>()
|
||||||
?.let { content ->
|
?.let { content ->
|
||||||
SerializablePowerLevelsContent(
|
SafePowerLevelContent(
|
||||||
ban = content.ban,
|
ban = content.ban,
|
||||||
kick = content.kick,
|
kick = content.kick,
|
||||||
invite = content.invite,
|
invite = content.invite,
|
||||||
|
@ -55,7 +55,7 @@ internal data class SearchRequestRoomEvents(
|
|||||||
* Requests the server return the current state for each room returned.
|
* Requests the server return the current state for each room returned.
|
||||||
*/
|
*/
|
||||||
@Json(name = "include_state")
|
@Json(name = "include_state")
|
||||||
val include_state: Boolean? = null
|
val includeState: Boolean? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests that the server partitions the result set based on the provided list of keys.
|
* Requests that the server partitions the result set based on the provided list of keys.
|
||||||
|
@ -213,7 +213,7 @@ internal class RoomSyncHandler @Inject constructor(
|
|||||||
val isInitialSync = insertType == EventInsertType.INITIAL_SYNC
|
val isInitialSync = insertType == EventInsertType.INITIAL_SYNC
|
||||||
|
|
||||||
val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed)
|
val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed)
|
||||||
?._roomSyncEphemeral
|
?.roomSyncEphemeral
|
||||||
?.events
|
?.events
|
||||||
?.takeIf { it.isNotEmpty() }
|
?.takeIf { it.isNotEmpty() }
|
||||||
?.let { handleEphemeral(realm, roomId, it, insertType == EventInsertType.INITIAL_SYNC, aggregator) }
|
?.let { handleEphemeral(realm, roomId, it, insertType == EventInsertType.INITIAL_SYNC, aggregator) }
|
||||||
|
@ -68,7 +68,7 @@ internal class DefaultSessionAccountDataService @Inject constructor(
|
|||||||
val params = UpdateUserAccountDataTask.AnyParams(type = type, any = content)
|
val params = UpdateUserAccountDataTask.AnyParams(type = type, any = content)
|
||||||
awaitCallback<Unit> { callback ->
|
awaitCallback<Unit> { callback ->
|
||||||
updateUserAccountDataTask.configureWith(params) {
|
updateUserAccountDataTask.configureWith(params) {
|
||||||
this.retryCount = 5 // TODO: Need to refactor retrying out into a helper method.
|
this.retryCount = 5 // TODO Need to refactor retrying out into a helper method.
|
||||||
this.callback = callback
|
this.callback = callback
|
||||||
}
|
}
|
||||||
.executeBy(taskExecutor)
|
.executeBy(taskExecutor)
|
||||||
|
@ -151,7 +151,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh
|
|||||||
override fun sendError(message: String, eventData: JsonDict) {
|
override fun sendError(message: String, eventData: JsonDict) {
|
||||||
Timber.e("## sendError() : eventData $eventData failed $message")
|
Timber.e("## sendError() : eventData $eventData failed $message")
|
||||||
|
|
||||||
// TODO: JS has an additional optional parameter: nestedError
|
// TODO JS has an additional optional parameter: nestedError
|
||||||
val params = HashMap<String, Map<String, String>>()
|
val params = HashMap<String, Map<String, String>>()
|
||||||
val subMap = HashMap<String, String>()
|
val subMap = HashMap<String, String>()
|
||||||
subMap["message"] = message
|
subMap["message"] = message
|
||||||
|
@ -81,7 +81,7 @@ class DefaultAddPusherTaskTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a persisted push entity and SetPush API fails when adding Pusher then mutates persisted result with Failed registration state and rethrows error`() {
|
fun `given a persisted push entity and SetPush API fails when adding Pusher then mutates persisted result with Failed registration state and rethrows`() {
|
||||||
val realmResult = PusherEntity()
|
val realmResult = PusherEntity()
|
||||||
monarchy.givenWhereReturns(result = realmResult)
|
monarchy.givenWhereReturns(result = realmResult)
|
||||||
pushersAPI.givenSetPusherErrors(SocketException())
|
pushersAPI.givenSetPusherErrors(SocketException())
|
||||||
|
@ -60,7 +60,7 @@ private short
|
|||||||
final short
|
final short
|
||||||
|
|
||||||
### Line length is limited to 160 chars. Please split long lines
|
### Line length is limited to 160 chars. Please split long lines
|
||||||
[^─]{161}
|
#[^─]{161}
|
||||||
|
|
||||||
### "DO NOT COMMIT" has been committed
|
### "DO NOT COMMIT" has been committed
|
||||||
DO NOT COMMIT
|
DO NOT COMMIT
|
||||||
|
98
tools/detekt/detekt.yml
Normal file
98
tools/detekt/detekt.yml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Default rules: https://github.com/detekt/detekt/blob/main/detekt-core/src/main/resources/default-detekt-config.yml
|
||||||
|
|
||||||
|
style:
|
||||||
|
MaxLineLength:
|
||||||
|
# Default is 120
|
||||||
|
maxLineLength: 160
|
||||||
|
MagicNumber:
|
||||||
|
active: false
|
||||||
|
ReturnCount:
|
||||||
|
active: false
|
||||||
|
UnnecessaryAbstractClass:
|
||||||
|
active: false
|
||||||
|
FunctionOnlyReturningConstant:
|
||||||
|
active: false
|
||||||
|
UnusedPrivateMember:
|
||||||
|
# TODO Enable it
|
||||||
|
active: false
|
||||||
|
ThrowsCount:
|
||||||
|
active: false
|
||||||
|
LoopWithTooManyJumpStatements:
|
||||||
|
active: false
|
||||||
|
SerialVersionUIDInSerializableClass:
|
||||||
|
active: false
|
||||||
|
ProtectedMemberInFinalClass:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
empty-blocks:
|
||||||
|
EmptyFunctionBlock:
|
||||||
|
active: false
|
||||||
|
EmptySecondaryConstructor:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
potential-bugs:
|
||||||
|
ImplicitDefaultLocale:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
exceptions:
|
||||||
|
TooGenericExceptionCaught:
|
||||||
|
active: false
|
||||||
|
SwallowedException:
|
||||||
|
active: false
|
||||||
|
ThrowingExceptionsWithoutMessageOrCause:
|
||||||
|
active: false
|
||||||
|
TooGenericExceptionThrown:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
complexity:
|
||||||
|
TooManyFunctions:
|
||||||
|
active: false
|
||||||
|
LongMethod:
|
||||||
|
active: false
|
||||||
|
LongParameterList:
|
||||||
|
active: false
|
||||||
|
ComplexMethod:
|
||||||
|
active: false
|
||||||
|
NestedBlockDepth:
|
||||||
|
active: false
|
||||||
|
ComplexCondition:
|
||||||
|
active: false
|
||||||
|
LargeClass:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
naming:
|
||||||
|
VariableNaming:
|
||||||
|
# TODO Enable it
|
||||||
|
active: false
|
||||||
|
TopLevelPropertyNaming:
|
||||||
|
# TODO Enable it
|
||||||
|
active: false
|
||||||
|
|
||||||
|
performance:
|
||||||
|
SpreadOperator:
|
||||||
|
active: false
|
||||||
|
|
||||||
|
# Note: all rules for `comments` are disabled by default, but I put them here to be aware of their existence
|
||||||
|
comments:
|
||||||
|
AbsentOrWrongFileLicense:
|
||||||
|
active: false
|
||||||
|
licenseTemplateFile: 'license.template'
|
||||||
|
licenseTemplateIsRegex: false
|
||||||
|
CommentOverPrivateFunction:
|
||||||
|
active: false
|
||||||
|
CommentOverPrivateProperty:
|
||||||
|
active: false
|
||||||
|
DeprecatedBlockTag:
|
||||||
|
active: true
|
||||||
|
EndOfSentenceFormat:
|
||||||
|
# TODO Enable it
|
||||||
|
active: false
|
||||||
|
OutdatedDocumentation:
|
||||||
|
# TODO Enable it
|
||||||
|
active: false
|
||||||
|
UndocumentedPublicClass:
|
||||||
|
active: false
|
||||||
|
UndocumentedPublicFunction:
|
||||||
|
active: false
|
||||||
|
UndocumentedPublicProperty:
|
||||||
|
active: false
|
@ -8,7 +8,7 @@ import im.vector.app.core.extensions.addFragment
|
|||||||
import im.vector.app.core.platform.ToolbarConfigurable
|
import im.vector.app.core.platform.ToolbarConfigurable
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
|
|
||||||
//TODO: add this activity to manifest
|
//TODO add this activity to manifest
|
||||||
class ${activityClass} : VectorBaseActivity(), ToolbarConfigurable {
|
class ${activityClass} : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
|||||||
data class ${fragmentArgsClass}() : Parcelable
|
data class ${fragmentArgsClass}() : Parcelable
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
//TODO: add this fragment into FragmentModule
|
//TODO add this fragment into FragmentModule
|
||||||
class ${fragmentClass} @Inject constructor(
|
class ${fragmentClass} @Inject constructor(
|
||||||
private val viewModelFactory: ${viewModelClass}.Factory
|
private val viewModelFactory: ${viewModelClass}.Factory
|
||||||
) : VectorBaseFragment(), ${viewModelClass}.Factory by viewModelFactory {
|
) : VectorBaseFragment(), ${viewModelClass}.Factory by viewModelFactory {
|
||||||
|
@ -87,7 +87,7 @@ class ActiveSessionHolder @Inject constructor(private val activeSessionDataSourc
|
|||||||
?: throw IllegalStateException("You should authenticate before using this")
|
?: throw IllegalStateException("You should authenticate before using this")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Stop sync ?
|
// TODO Stop sync ?
|
||||||
// fun switchToSession(sessionParams: SessionParams) {
|
// fun switchToSession(sessionParams: SessionParams) {
|
||||||
// val newActiveSession = authenticationService.getSession(sessionParams)
|
// val newActiveSession = authenticationService.getSession(sessionParams)
|
||||||
// activeSession.set(newActiveSession)
|
// activeSession.set(newActiveSession)
|
||||||
|
@ -134,7 +134,7 @@ object VectorStaticModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
|
fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
|
||||||
// TODO: handle session injection better
|
// TODO handle session injection better
|
||||||
return activeSessionHolder.getActiveSession()
|
return activeSessionHolder.getActiveSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,23 +27,23 @@ data class UserProperties(
|
|||||||
/**
|
/**
|
||||||
* Whether the user has the favourites space enabled
|
* Whether the user has the favourites space enabled
|
||||||
*/
|
*/
|
||||||
val WebMetaSpaceFavouritesEnabled: Boolean? = null,
|
val webMetaSpaceFavouritesEnabled: Boolean? = null,
|
||||||
/**
|
/**
|
||||||
* Whether the user has the home space set to all rooms
|
* Whether the user has the home space set to all rooms
|
||||||
*/
|
*/
|
||||||
val WebMetaSpaceHomeAllRooms: Boolean? = null,
|
val webMetaSpaceHomeAllRooms: Boolean? = null,
|
||||||
/**
|
/**
|
||||||
* Whether the user has the home space enabled
|
* Whether the user has the home space enabled
|
||||||
*/
|
*/
|
||||||
val WebMetaSpaceHomeEnabled: Boolean? = null,
|
val webMetaSpaceHomeEnabled: Boolean? = null,
|
||||||
/**
|
/**
|
||||||
* Whether the user has the other rooms space enabled
|
* Whether the user has the other rooms space enabled
|
||||||
*/
|
*/
|
||||||
val WebMetaSpaceOrphansEnabled: Boolean? = null,
|
val webMetaSpaceOrphansEnabled: Boolean? = null,
|
||||||
/**
|
/**
|
||||||
* Whether the user has the people space enabled
|
* Whether the user has the people space enabled
|
||||||
*/
|
*/
|
||||||
val WebMetaSpacePeopleEnabled: Boolean? = null,
|
val webMetaSpacePeopleEnabled: Boolean? = null,
|
||||||
/**
|
/**
|
||||||
* The selected messaging use case during the onboarding flow.
|
* The selected messaging use case during the onboarding flow.
|
||||||
*/
|
*/
|
||||||
@ -82,11 +82,11 @@ data class UserProperties(
|
|||||||
|
|
||||||
fun getProperties(): Map<String, Any>? {
|
fun getProperties(): Map<String, Any>? {
|
||||||
return mutableMapOf<String, Any>().apply {
|
return mutableMapOf<String, Any>().apply {
|
||||||
WebMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) }
|
webMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) }
|
||||||
WebMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) }
|
webMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) }
|
||||||
WebMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) }
|
webMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) }
|
||||||
WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) }
|
webMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) }
|
||||||
WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) }
|
webMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) }
|
||||||
ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) }
|
ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) }
|
||||||
numFavouriteRooms?.let { put("numFavouriteRooms", it) }
|
numFavouriteRooms?.let { put("numFavouriteRooms", it) }
|
||||||
numSpaces?.let { put("numSpaces", it) }
|
numSpaces?.let { put("numSpaces", it) }
|
||||||
|
@ -53,7 +53,7 @@ class AutoCompleter @AssistedInject constructor(
|
|||||||
@Assisted val isInThreadTimeline: Boolean,
|
@Assisted val isInThreadTimeline: Boolean,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
||||||
AutocompleteCommandPresenterFactory: AutocompleteCommandPresenter.Factory,
|
autocompleteCommandPresenterFactory: AutocompleteCommandPresenter.Factory,
|
||||||
private val autocompleteMemberPresenterFactory: AutocompleteMemberPresenter.Factory,
|
private val autocompleteMemberPresenterFactory: AutocompleteMemberPresenter.Factory,
|
||||||
private val autocompleteRoomPresenter: AutocompleteRoomPresenter,
|
private val autocompleteRoomPresenter: AutocompleteRoomPresenter,
|
||||||
private val autocompleteGroupPresenter: AutocompleteGroupPresenter,
|
private val autocompleteGroupPresenter: AutocompleteGroupPresenter,
|
||||||
@ -68,7 +68,7 @@ class AutoCompleter @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val autocompleteCommandPresenter: AutocompleteCommandPresenter by lazy {
|
private val autocompleteCommandPresenter: AutocompleteCommandPresenter by lazy {
|
||||||
AutocompleteCommandPresenterFactory.create(isInThreadTimeline)
|
autocompleteCommandPresenterFactory.create(isInThreadTimeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var editText: EditText? = null
|
private var editText: EditText? = null
|
||||||
|
@ -225,7 +225,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) {
|
override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) {
|
||||||
when (state) {
|
when (state) {
|
||||||
is AudioMessagePlaybackTracker.Listener.State.Recording -> {
|
is AudioMessagePlaybackTracker.Listener.State.Recording -> {
|
||||||
voiceMessageViews.renderRecordingWaveform(state.amplitudeList.toTypedArray())
|
voiceMessageViews.renderRecordingWaveform(state.amplitudeList.toList())
|
||||||
}
|
}
|
||||||
is AudioMessagePlaybackTracker.Listener.State.Playing -> {
|
is AudioMessagePlaybackTracker.Listener.State.Playing -> {
|
||||||
voiceMessageViews.renderPlaying(state)
|
voiceMessageViews.renderPlaying(state)
|
||||||
|
@ -345,10 +345,10 @@ class VoiceMessageViews(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renderRecordingWaveform(amplitudeList: Array<Int>) {
|
fun renderRecordingWaveform(amplitudeList: List<Int>) {
|
||||||
views.voicePlaybackWaveform.doOnLayout { waveFormView ->
|
views.voicePlaybackWaveform.doOnLayout { waveFormView ->
|
||||||
val waveformColor = ThemeUtils.getColor(waveFormView.context, R.attr.vctr_content_quaternary)
|
val waveformColor = ThemeUtils.getColor(waveFormView.context, R.attr.vctr_content_quaternary)
|
||||||
amplitudeList.iterator().forEach {
|
amplitudeList.forEach {
|
||||||
(waveFormView as AudioWaveformView).add(AudioWaveformView.FFT(it.toFloat(), waveformColor))
|
(waveFormView as AudioWaveformView).add(AudioWaveformView.FFT(it.toFloat(), waveformColor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
||||||
)
|
)
|
||||||
} catch (e: MXCryptoError) {
|
} catch (ignore: MXCryptoError) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,9 +309,9 @@ class Login2Variant(
|
|||||||
activity.finish()
|
activity.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateWithState(LoginViewState2: LoginViewState2) {
|
private fun updateWithState(loginViewState2: LoginViewState2) {
|
||||||
// Loading
|
// Loading
|
||||||
setIsLoading(LoginViewState2.isLoading)
|
setIsLoading(loginViewState2.isLoading)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack for AccountCreatedFragment
|
// Hack for AccountCreatedFragment
|
||||||
|
@ -288,8 +288,8 @@ class FtueAuthVariant(
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onServerSelectionDone(OnboardingViewEvents: OnboardingViewEvents.OnServerSelectionDone) {
|
private fun onServerSelectionDone(onboardingViewEvents: OnboardingViewEvents.OnServerSelectionDone) {
|
||||||
when (OnboardingViewEvents.serverType) {
|
when (onboardingViewEvents.serverType) {
|
||||||
ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow
|
ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow
|
||||||
ServerType.EMS,
|
ServerType.EMS,
|
||||||
ServerType.Other -> activity.addFragmentToBackstack(
|
ServerType.Other -> activity.addFragmentToBackstack(
|
||||||
@ -301,9 +301,9 @@ class FtueAuthVariant(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSignModeSelected(OnboardingViewEvents: OnboardingViewEvents.OnSignModeSelected) = withState(onboardingViewModel) { state ->
|
private fun onSignModeSelected(onboardingViewEvents: OnboardingViewEvents.OnSignModeSelected) = withState(onboardingViewModel) { state ->
|
||||||
// state.signMode could not be ready yet. So use value from the ViewEvent
|
// state.signMode could not be ready yet. So use value from the ViewEvent
|
||||||
when (OnboardingViewEvents.signMode) {
|
when (onboardingViewEvents.signMode) {
|
||||||
SignMode.Unknown -> error("Sign mode has to be set before calling this method")
|
SignMode.Unknown -> error("Sign mode has to be set before calling this method")
|
||||||
SignMode.SignUp -> Unit // This case is processed in handleOnboardingViewEvents
|
SignMode.SignUp -> Unit // This case is processed in handleOnboardingViewEvents
|
||||||
SignMode.SignIn -> handleSignInSelected(state)
|
SignMode.SignIn -> handleSignInSelected(state)
|
||||||
|
@ -29,7 +29,7 @@ import im.vector.app.core.platform.VectorBaseActivity
|
|||||||
import im.vector.app.databinding.ActivitySimpleBinding
|
import im.vector.app.databinding.ActivitySimpleBinding
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class QrCodeScannerActivity() : VectorBaseActivity<ActivitySimpleBinding>() {
|
class QrCodeScannerActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||||
|
|
||||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ class VectorUncaughtExceptionHandler @Inject constructor(
|
|||||||
* @param throwable the throwable
|
* @param throwable the throwable
|
||||||
* @return the exception description
|
* @return the exception description
|
||||||
*/
|
*/
|
||||||
|
@Suppress("PrintStackTrace")
|
||||||
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
||||||
Timber.v("Uncaught exception: $throwable")
|
Timber.v("Uncaught exception: $throwable")
|
||||||
preferences.edit(commit = true) {
|
preferences.edit(commit = true) {
|
||||||
|
@ -44,8 +44,8 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* TODO: Loading indicator while getting emoji data source?
|
* TODO Loading indicator while getting emoji data source?
|
||||||
* TODO: Finish Refactor to vector base activity
|
* TODO Finish Refactor to vector base activity
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPickerBinding>(),
|
class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPickerBinding>(),
|
||||||
|
@ -41,9 +41,9 @@ import kotlin.math.abs
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* TODO: Configure Span using available width and emoji size
|
* TODO Configure Span using available width and emoji size
|
||||||
* TODO: Performances
|
* TODO Performances
|
||||||
* TODO: Scroll to section - Find a way to snap section to the top
|
* TODO Scroll to section - Find a way to snap section to the top
|
||||||
*/
|
*/
|
||||||
class EmojiRecyclerAdapter @Inject constructor() :
|
class EmojiRecyclerAdapter @Inject constructor() :
|
||||||
RecyclerView.Adapter<EmojiRecyclerAdapter.ViewHolder>() {
|
RecyclerView.Adapter<EmojiRecyclerAdapter.ViewHolder>() {
|
||||||
|
@ -297,7 +297,7 @@ class CreateRoomViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should this be non-cancellable?
|
// TODO Should this be non-cancellable?
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
runCatching { session.roomService().createRoom(createRoomParams) }.fold(
|
runCatching { session.roomService().createRoom(createRoomParams) }.fold(
|
||||||
{ roomId ->
|
{ roomId ->
|
||||||
|
@ -308,49 +308,55 @@ class OnboardingViewModelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given personalisation enabled and registration has started and has dummy step to do, when handling action, then ignores other steps and executes dummy`() = runTest {
|
fun `given personalisation enabled and registration has started and has dummy step to do, when handling action, then ignores other steps and does dummy`() {
|
||||||
fakeVectorFeatures.givenPersonalisationEnabled()
|
runTest {
|
||||||
givenSuccessfulRegistrationForStartAndDummySteps(missingStages = listOf(Stage.Dummy(mandatory = true)))
|
fakeVectorFeatures.givenPersonalisationEnabled()
|
||||||
val test = viewModel.test()
|
givenSuccessfulRegistrationForStartAndDummySteps(missingStages = listOf(Stage.Dummy(mandatory = true)))
|
||||||
|
val test = viewModel.test()
|
||||||
|
|
||||||
viewModel.handle(OnboardingAction.PostRegisterAction(A_LOADABLE_REGISTER_ACTION))
|
viewModel.handle(OnboardingAction.PostRegisterAction(A_LOADABLE_REGISTER_ACTION))
|
||||||
|
|
||||||
test
|
test
|
||||||
.assertStatesChanges(
|
.assertStatesChanges(
|
||||||
initialState,
|
initialState,
|
||||||
{ copy(isLoading = true) },
|
{ copy(isLoading = true) },
|
||||||
{ copy(isLoading = false, personalizationState = A_HOMESERVER_CAPABILITIES.toPersonalisationState()) }
|
{ copy(isLoading = false, personalizationState = A_HOMESERVER_CAPABILITIES.toPersonalisationState()) }
|
||||||
)
|
)
|
||||||
.assertEvents(OnboardingViewEvents.OnAccountCreated)
|
.assertEvents(OnboardingViewEvents.OnAccountCreated)
|
||||||
.finish()
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given changing profile picture is supported, when updating display name, then updates upstream user display name and moves to choose profile picture`() = runTest {
|
fun `given changing profile avatar is supported, when updating display name, then updates upstream user display name and moves to choose profile avatar`() {
|
||||||
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true)))
|
runTest {
|
||||||
val test = viewModel.test()
|
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true)))
|
||||||
|
val test = viewModel.test()
|
||||||
|
|
||||||
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
||||||
|
|
||||||
test
|
test
|
||||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||||
.assertEvents(OnboardingViewEvents.OnChooseProfilePicture)
|
.assertEvents(OnboardingViewEvents.OnChooseProfilePicture)
|
||||||
.finish()
|
.finish()
|
||||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given changing profile picture is not supported, when updating display name, then updates upstream user display name and completes personalization`() = runTest {
|
fun `given changing profile avatar is not supported, when updating display name, then updates upstream user display name and completes personalization`() {
|
||||||
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false)))
|
runTest {
|
||||||
val test = viewModel.test()
|
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false)))
|
||||||
|
val test = viewModel.test()
|
||||||
|
|
||||||
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
||||||
|
|
||||||
test
|
test
|
||||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||||
.assertEvents(OnboardingViewEvents.OnPersonalizationComplete)
|
.assertEvents(OnboardingViewEvents.OnPersonalizationComplete)
|
||||||
.finish()
|
.finish()
|
||||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -34,7 +34,11 @@ class FakeSharedSecretStorageService : SharedSecretStorageService {
|
|||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun generateKeyWithPassphrase(keyId: String, keyName: String, passphrase: String, keySigner: KeySigner, progressListener: ProgressListener?): SsssKeyCreationInfo {
|
override suspend fun generateKeyWithPassphrase(keyId: String,
|
||||||
|
keyName: String,
|
||||||
|
passphrase: String,
|
||||||
|
keySigner: KeySigner,
|
||||||
|
progressListener: ProgressListener?): SsssKeyCreationInfo {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user