mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
commit
9234c60155
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -67,4 +67,4 @@ jobs:
|
||||
path: |
|
||||
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 }}
|
||||
path: |
|
||||
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 {
|
||||
// ktlint Plugin
|
||||
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
|
||||
// Detekt
|
||||
id "io.gitlab.arturbosch.detekt" version "1.20.0"
|
||||
}
|
||||
|
||||
// https://github.com/jeremylong/DependencyCheck
|
||||
@ -52,6 +54,7 @@ dependencyCheck {
|
||||
|
||||
allprojects {
|
||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||
apply plugin: "io.gitlab.arturbosch.detekt"
|
||||
|
||||
repositories {
|
||||
// Do not use `mavenCentral()`, it prevents Dependabot from working properly
|
||||
@ -119,7 +122,7 @@ allprojects {
|
||||
// display the corresponding rule
|
||||
verbose = true
|
||||
disabledRules = [
|
||||
// TODO: Re-enable these 4 rules after reformatting project
|
||||
// TODO Re-enable these 4 rules after reformatting project
|
||||
"indent",
|
||||
"experimental:argument-list-wrapping",
|
||||
"max-line-length",
|
||||
@ -140,6 +143,15 @@ allprojects {
|
||||
"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) {
|
||||
|
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.microutils',
|
||||
'io.github.reactivecircus.flowbinding',
|
||||
'io.gitlab.arturbosch.detekt',
|
||||
'io.grpc',
|
||||
'io.jsonwebtoken',
|
||||
'io.kindedj',
|
||||
@ -195,6 +196,7 @@ ext.groups = [
|
||||
'org.testng',
|
||||
'org.threeten',
|
||||
'org.webjars',
|
||||
'org.yaml',
|
||||
'ru.noties',
|
||||
'xerces',
|
||||
'xml-apis',
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.lib.multipicker
|
||||
|
||||
class MultiPicker<T> {
|
||||
class MultiPicker<T> private constructor() {
|
||||
|
||||
companion object Type {
|
||||
val IMAGE by lazy { MultiPicker<ImagePicker>() }
|
||||
|
@ -22,15 +22,15 @@ package org.matrix.android.sdk.api.logger
|
||||
* val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
|
||||
* 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 VOIP : LoggerTag("VOIP")
|
||||
object CRYPTO : LoggerTag("CRYPTO")
|
||||
|
||||
val value: String = if (parentTag == null) {
|
||||
_value
|
||||
name
|
||||
} else {
|
||||
"${parentTag.value}/$_value"
|
||||
"${parentTag.value}/$name"
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ import timber.log.Timber
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RoomGuestAccessContent(
|
||||
// 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
|
||||
"forbidden" -> GuestAccess.Forbidden
|
||||
else -> {
|
||||
Timber.w("Invalid value for GuestAccess: `$_guestAccess`")
|
||||
Timber.w("Invalid value for GuestAccess: `$guestAccessStr`")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
@ -22,15 +22,15 @@ import timber.log.Timber
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
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
|
||||
"shared" -> RoomHistoryVisibility.SHARED
|
||||
"invited" -> RoomHistoryVisibility.INVITED
|
||||
"joined" -> RoomHistoryVisibility.JOINED
|
||||
else -> {
|
||||
Timber.w("Invalid value for RoomHistoryVisibility: `$_historyVisibility`")
|
||||
Timber.w("Invalid value for RoomHistoryVisibility: `$historyVisibilityStr`")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import timber.log.Timber
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
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),
|
||||
* 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
|
||||
) {
|
||||
val joinRules: RoomJoinRules? = when (_joinRules) {
|
||||
val joinRules: RoomJoinRules? = when (joinRulesStr) {
|
||||
"public" -> RoomJoinRules.PUBLIC
|
||||
"invite" -> RoomJoinRules.INVITE
|
||||
"knock" -> RoomJoinRules.KNOCK
|
||||
"private" -> RoomJoinRules.PRIVATE
|
||||
"restricted" -> RoomJoinRules.RESTRICTED
|
||||
else -> {
|
||||
Timber.w("Invalid value for RoomJoinRules: `$_joinRules`")
|
||||
Timber.w("Invalid value for RoomJoinRules: `$joinRulesStr`")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class RestrictedRoomPreset(val homeServerCapabilities: HomeServerCapabilities, v
|
||||
type = EventType.STATE_ROOM_JOIN_RULES,
|
||||
stateKey = "",
|
||||
content = RoomJoinRulesContent(
|
||||
_joinRules = RoomJoinRules.RESTRICTED.value,
|
||||
joinRulesStr = RoomJoinRules.RESTRICTED.value,
|
||||
allowList = restrictedList
|
||||
).toContent()
|
||||
)
|
||||
|
@ -20,6 +20,6 @@ import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = false)
|
||||
sealed class LazyRoomSyncEphemeral {
|
||||
data class Parsed(val _roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral()
|
||||
data class Parsed(val roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral()
|
||||
object Stored : LazyRoomSyncEphemeral()
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ internal fun Versions.isLoginAndRegistrationSupportedBySdk(): Boolean {
|
||||
* Indicate if the homeserver support MSC3440 for threads
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ internal class PerSessionBackupQueryRateLimiter @Inject constructor(
|
||||
) {
|
||||
|
||||
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(
|
||||
|
@ -79,7 +79,7 @@ internal class RoomDecryptorProvider @Inject constructor(
|
||||
newSessionListeners.toList().forEach {
|
||||
try {
|
||||
it.onNewSession(roomId, senderKey, sessionId)
|
||||
} catch (e: Throwable) {
|
||||
} catch (ignore: Throwable) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ internal class MXMegolmEncryption(
|
||||
}
|
||||
|
||||
// Default rotation periods
|
||||
// TODO: Make it configurable via parameters
|
||||
// TODO Make it configurable via parameters
|
||||
// Session rotation periods
|
||||
private var sessionRotationPeriodMsgs: Int = 100
|
||||
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 {
|
||||
// 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)
|
||||
val deviceInfos = ArrayList<CryptoDeviceInfo>()
|
||||
for (userId in userIds) {
|
||||
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||
@SessionScope
|
||||
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.
|
||||
private var warnOnUnknownDevices = false
|
||||
|
||||
|
@ -42,7 +42,7 @@ internal class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7)
|
||||
val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures)
|
||||
it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
} catch (ignore: Throwable) {
|
||||
}
|
||||
|
||||
// Migrate frozen classes
|
||||
|
@ -69,6 +69,7 @@ internal class DefaultSendEventTask @Inject constructor(
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
// localEchoRepository.updateSendState(params.event.eventId!!, SendState.UNDELIVERED)
|
||||
Timber.w(e, "Unable to send the Event")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
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.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
@ -34,20 +33,15 @@ internal class DefaultUploadSignaturesTask @Inject constructor(
|
||||
) : UploadSignaturesTask {
|
||||
|
||||
override suspend fun execute(params: UploadSignaturesTask.Params) {
|
||||
try {
|
||||
val response = executeRequest(
|
||||
globalErrorReceiver,
|
||||
canRetry = true,
|
||||
maxRetriesCount = 10
|
||||
) {
|
||||
cryptoApi.uploadSignatures(params.signatures)
|
||||
}
|
||||
if (response.failures?.isNotEmpty() == true) {
|
||||
throw Throwable(response.failures.toString())
|
||||
}
|
||||
return
|
||||
} catch (f: Failure) {
|
||||
throw f
|
||||
val response = executeRequest(
|
||||
globalErrorReceiver,
|
||||
canRetry = true,
|
||||
maxRetriesCount = 10
|
||||
) {
|
||||
cryptoApi.uploadSignatures(params.signatures)
|
||||
}
|
||||
if (response.failures?.isNotEmpty() == true) {
|
||||
throw Throwable(response.failures.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ internal object CertUtil {
|
||||
builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions)
|
||||
val list = ArrayList<ConnectionSpec>()
|
||||
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://")) {
|
||||
list.add(ConnectionSpec.CLEARTEXT)
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ internal class DefaultFileService @Inject constructor(
|
||||
|
||||
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 existing = ongoing[url]
|
||||
if (existing != null) {
|
||||
|
@ -29,6 +29,6 @@ internal data class GroupSummaryRoomsSection(
|
||||
|
||||
@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;
|
||||
)
|
||||
|
@ -30,6 +30,6 @@ internal data class GroupSummaryUsersSection(
|
||||
|
||||
@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;
|
||||
)
|
||||
|
@ -16,14 +16,16 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.identity.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
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,
|
||||
/**The token from the call to store- invite..*/
|
||||
/** The token from the call to store- invite..*/
|
||||
val token: String,
|
||||
/** 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) {
|
||||
val body = if (joinRules == RoomJoinRules.RESTRICTED) {
|
||||
RoomJoinRulesContent(
|
||||
_joinRules = RoomJoinRules.RESTRICTED.value,
|
||||
joinRulesStr = RoomJoinRules.RESTRICTED.value,
|
||||
allowList = allowList
|
||||
).toContent()
|
||||
} 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.util.JsonDict
|
||||
|
||||
/**
|
||||
* Serializable object
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class SerializablePowerLevelsContent(
|
||||
internal data class SafePowerLevelContent(
|
||||
@Json(name = "ban") val ban: Int?,
|
||||
@Json(name = "kick") val kick: Int?,
|
||||
@Json(name = "invite") val invite: Int?,
|
||||
@ -41,7 +44,7 @@ internal data class SerializablePowerLevelsContent(
|
||||
internal fun JsonDict.toSafePowerLevelsContentDict(): JsonDict {
|
||||
return toModel<PowerLevelsContent>()
|
||||
?.let { content ->
|
||||
SerializablePowerLevelsContent(
|
||||
SafePowerLevelContent(
|
||||
ban = content.ban,
|
||||
kick = content.kick,
|
||||
invite = content.invite,
|
||||
|
@ -55,7 +55,7 @@ internal data class SearchRequestRoomEvents(
|
||||
* Requests the server return the current state for each room returned.
|
||||
*/
|
||||
@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.
|
||||
|
@ -213,7 +213,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
val isInitialSync = insertType == EventInsertType.INITIAL_SYNC
|
||||
|
||||
val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed)
|
||||
?._roomSyncEphemeral
|
||||
?.roomSyncEphemeral
|
||||
?.events
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.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)
|
||||
awaitCallback<Unit> { callback ->
|
||||
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
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
|
@ -151,7 +151,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh
|
||||
override fun sendError(message: String, eventData: JsonDict) {
|
||||
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 subMap = HashMap<String, String>()
|
||||
subMap["message"] = message
|
||||
|
@ -81,7 +81,7 @@ class DefaultAddPusherTaskTest {
|
||||
}
|
||||
|
||||
@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()
|
||||
monarchy.givenWhereReturns(result = realmResult)
|
||||
pushersAPI.givenSetPusherErrors(SocketException())
|
||||
|
@ -60,7 +60,7 @@ private short
|
||||
final short
|
||||
|
||||
### Line length is limited to 160 chars. Please split long lines
|
||||
[^─]{161}
|
||||
#[^─]{161}
|
||||
|
||||
### "DO NOT COMMIT" has been committed
|
||||
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.VectorBaseActivity
|
||||
|
||||
//TODO: add this activity to manifest
|
||||
//TODO add this activity to manifest
|
||||
class ${activityClass} : VectorBaseActivity(), ToolbarConfigurable {
|
||||
|
||||
companion object {
|
||||
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
||||
data class ${fragmentArgsClass}() : Parcelable
|
||||
</#if>
|
||||
|
||||
//TODO: add this fragment into FragmentModule
|
||||
//TODO add this fragment into FragmentModule
|
||||
class ${fragmentClass} @Inject constructor(
|
||||
private val viewModelFactory: ${viewModelClass}.Factory
|
||||
) : VectorBaseFragment(), ${viewModelClass}.Factory by viewModelFactory {
|
||||
|
@ -87,7 +87,7 @@ class ActiveSessionHolder @Inject constructor(private val activeSessionDataSourc
|
||||
?: throw IllegalStateException("You should authenticate before using this")
|
||||
}
|
||||
|
||||
// TODO: Stop sync ?
|
||||
// TODO Stop sync ?
|
||||
// fun switchToSession(sessionParams: SessionParams) {
|
||||
// val newActiveSession = authenticationService.getSession(sessionParams)
|
||||
// activeSession.set(newActiveSession)
|
||||
|
@ -134,7 +134,7 @@ object VectorStaticModule {
|
||||
|
||||
@Provides
|
||||
fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
|
||||
// TODO: handle session injection better
|
||||
// TODO handle session injection better
|
||||
return activeSessionHolder.getActiveSession()
|
||||
}
|
||||
|
||||
|
@ -27,23 +27,23 @@ data class UserProperties(
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
val WebMetaSpaceHomeAllRooms: Boolean? = null,
|
||||
val webMetaSpaceHomeAllRooms: Boolean? = null,
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
val WebMetaSpaceOrphansEnabled: Boolean? = null,
|
||||
val webMetaSpaceOrphansEnabled: Boolean? = null,
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -82,11 +82,11 @@ data class UserProperties(
|
||||
|
||||
fun getProperties(): Map<String, Any>? {
|
||||
return mutableMapOf<String, Any>().apply {
|
||||
WebMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) }
|
||||
WebMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) }
|
||||
WebMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) }
|
||||
WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) }
|
||||
WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) }
|
||||
webMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) }
|
||||
webMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) }
|
||||
webMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) }
|
||||
webMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) }
|
||||
webMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) }
|
||||
ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) }
|
||||
numFavouriteRooms?.let { put("numFavouriteRooms", it) }
|
||||
numSpaces?.let { put("numSpaces", it) }
|
||||
|
@ -53,7 +53,7 @@ class AutoCompleter @AssistedInject constructor(
|
||||
@Assisted val isInThreadTimeline: Boolean,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val commandAutocompletePolicy: CommandAutocompletePolicy,
|
||||
AutocompleteCommandPresenterFactory: AutocompleteCommandPresenter.Factory,
|
||||
autocompleteCommandPresenterFactory: AutocompleteCommandPresenter.Factory,
|
||||
private val autocompleteMemberPresenterFactory: AutocompleteMemberPresenter.Factory,
|
||||
private val autocompleteRoomPresenter: AutocompleteRoomPresenter,
|
||||
private val autocompleteGroupPresenter: AutocompleteGroupPresenter,
|
||||
@ -68,7 +68,7 @@ class AutoCompleter @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private val autocompleteCommandPresenter: AutocompleteCommandPresenter by lazy {
|
||||
AutocompleteCommandPresenterFactory.create(isInThreadTimeline)
|
||||
autocompleteCommandPresenterFactory.create(isInThreadTimeline)
|
||||
}
|
||||
|
||||
private var editText: EditText? = null
|
||||
|
@ -225,7 +225,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) {
|
||||
when (state) {
|
||||
is AudioMessagePlaybackTracker.Listener.State.Recording -> {
|
||||
voiceMessageViews.renderRecordingWaveform(state.amplitudeList.toTypedArray())
|
||||
voiceMessageViews.renderRecordingWaveform(state.amplitudeList.toList())
|
||||
}
|
||||
is AudioMessagePlaybackTracker.Listener.State.Playing -> {
|
||||
voiceMessageViews.renderPlaying(state)
|
||||
|
@ -345,10 +345,10 @@ class VoiceMessageViews(
|
||||
}
|
||||
}
|
||||
|
||||
fun renderRecordingWaveform(amplitudeList: Array<Int>) {
|
||||
fun renderRecordingWaveform(amplitudeList: List<Int>) {
|
||||
views.voicePlaybackWaveform.doOnLayout { waveFormView ->
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ class NotifiableEventResolver @Inject constructor(
|
||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
||||
)
|
||||
} catch (e: MXCryptoError) {
|
||||
} catch (ignore: MXCryptoError) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,9 +309,9 @@ class Login2Variant(
|
||||
activity.finish()
|
||||
}
|
||||
|
||||
private fun updateWithState(LoginViewState2: LoginViewState2) {
|
||||
private fun updateWithState(loginViewState2: LoginViewState2) {
|
||||
// Loading
|
||||
setIsLoading(LoginViewState2.isLoading)
|
||||
setIsLoading(loginViewState2.isLoading)
|
||||
}
|
||||
|
||||
// Hack for AccountCreatedFragment
|
||||
|
@ -288,8 +288,8 @@ class FtueAuthVariant(
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun onServerSelectionDone(OnboardingViewEvents: OnboardingViewEvents.OnServerSelectionDone) {
|
||||
when (OnboardingViewEvents.serverType) {
|
||||
private fun onServerSelectionDone(onboardingViewEvents: OnboardingViewEvents.OnServerSelectionDone) {
|
||||
when (onboardingViewEvents.serverType) {
|
||||
ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow
|
||||
ServerType.EMS,
|
||||
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
|
||||
when (OnboardingViewEvents.signMode) {
|
||||
when (onboardingViewEvents.signMode) {
|
||||
SignMode.Unknown -> error("Sign mode has to be set before calling this method")
|
||||
SignMode.SignUp -> Unit // This case is processed in handleOnboardingViewEvents
|
||||
SignMode.SignIn -> handleSignInSelected(state)
|
||||
|
@ -29,7 +29,7 @@ import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
|
||||
@AndroidEntryPoint
|
||||
class QrCodeScannerActivity() : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
class QrCodeScannerActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
|
||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||
|
||||
|
@ -61,6 +61,7 @@ class VectorUncaughtExceptionHandler @Inject constructor(
|
||||
* @param throwable the throwable
|
||||
* @return the exception description
|
||||
*/
|
||||
@Suppress("PrintStackTrace")
|
||||
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
||||
Timber.v("Uncaught exception: $throwable")
|
||||
preferences.edit(commit = true) {
|
||||
|
@ -44,8 +44,8 @@ import javax.inject.Inject
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO: Loading indicator while getting emoji data source?
|
||||
* TODO: Finish Refactor to vector base activity
|
||||
* TODO Loading indicator while getting emoji data source?
|
||||
* TODO Finish Refactor to vector base activity
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPickerBinding>(),
|
||||
|
@ -41,9 +41,9 @@ import kotlin.math.abs
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO: Configure Span using available width and emoji size
|
||||
* TODO: Performances
|
||||
* TODO: Scroll to section - Find a way to snap section to the top
|
||||
* TODO Configure Span using available width and emoji size
|
||||
* TODO Performances
|
||||
* TODO Scroll to section - Find a way to snap section to the top
|
||||
*/
|
||||
class EmojiRecyclerAdapter @Inject constructor() :
|
||||
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 {
|
||||
runCatching { session.roomService().createRoom(createRoomParams) }.fold(
|
||||
{ roomId ->
|
||||
|
@ -308,49 +308,55 @@ class OnboardingViewModelTest {
|
||||
}
|
||||
|
||||
@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 {
|
||||
fakeVectorFeatures.givenPersonalisationEnabled()
|
||||
givenSuccessfulRegistrationForStartAndDummySteps(missingStages = listOf(Stage.Dummy(mandatory = true)))
|
||||
val test = viewModel.test()
|
||||
fun `given personalisation enabled and registration has started and has dummy step to do, when handling action, then ignores other steps and does dummy`() {
|
||||
runTest {
|
||||
fakeVectorFeatures.givenPersonalisationEnabled()
|
||||
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
|
||||
.assertStatesChanges(
|
||||
initialState,
|
||||
{ copy(isLoading = true) },
|
||||
{ copy(isLoading = false, personalizationState = A_HOMESERVER_CAPABILITIES.toPersonalisationState()) }
|
||||
)
|
||||
.assertEvents(OnboardingViewEvents.OnAccountCreated)
|
||||
.finish()
|
||||
test
|
||||
.assertStatesChanges(
|
||||
initialState,
|
||||
{ copy(isLoading = true) },
|
||||
{ copy(isLoading = false, personalizationState = A_HOMESERVER_CAPABILITIES.toPersonalisationState()) }
|
||||
)
|
||||
.assertEvents(OnboardingViewEvents.OnAccountCreated)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true)))
|
||||
val test = viewModel.test()
|
||||
fun `given changing profile avatar is supported, when updating display name, then updates upstream user display name and moves to choose profile avatar`() {
|
||||
runTest {
|
||||
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
|
||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||
.assertEvents(OnboardingViewEvents.OnChooseProfilePicture)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
test
|
||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||
.assertEvents(OnboardingViewEvents.OnChooseProfilePicture)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given changing profile picture is not supported, when updating display name, then updates upstream user display name and completes personalization`() = runTest {
|
||||
viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false)))
|
||||
val test = viewModel.test()
|
||||
fun `given changing profile avatar is not supported, when updating display name, then updates upstream user display name and completes personalization`() {
|
||||
runTest {
|
||||
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
|
||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||
.assertEvents(OnboardingViewEvents.OnPersonalizationComplete)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
test
|
||||
.assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates())
|
||||
.assertEvents(OnboardingViewEvents.OnPersonalizationComplete)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -34,7 +34,11 @@ class FakeSharedSecretStorageService : SharedSecretStorageService {
|
||||
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")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user