Merge pull request #2481 from vector-im/feature/bma/upgrade

Upgrade of some library + cleanup
This commit is contained in:
Benoit Marty 2020-12-03 09:50:43 +01:00 committed by GitHub
commit a911492a9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 116 additions and 141 deletions

View file

@ -20,7 +20,8 @@ SDK API changes ⚠️:
- -
Build 🧱: Build 🧱:
- - Upgrade some dependencies and Kotlin version
- Use fragment-ktx and preference-ktx dependencies (fix lint issue KtxExtensionAvailable)
Test: Test:
- -

View file

@ -66,7 +66,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.recyclerview:recyclerview:1.1.0" implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'

View file

@ -2,8 +2,8 @@
buildscript { buildscript {
// Ref: https://kotlinlang.org/releases.html // Ref: https://kotlinlang.org/releases.html
ext.kotlin_version = '1.4.10' ext.kotlin_version = '1.4.20'
ext.kotlin_coroutines_version = "1.3.9" ext.kotlin_coroutines_version = "1.4.1"
repositories { repositories {
google() google()
jcenter() jcenter()
@ -12,7 +12,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.google.gms:google-services:4.3.4' classpath 'com.google.gms:google-services:4.3.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'

View file

@ -36,9 +36,9 @@ android {
dependencies { dependencies {
implementation project(":matrix-sdk-android") implementation project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
// Paging // Paging
implementation "androidx.paging:paging-runtime-ktx:2.1.2" implementation "androidx.paging:paging-runtime-ktx:2.1.2"

View file

@ -21,34 +21,36 @@ import org.matrix.android.sdk.api.util.Cancelable
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Single import io.reactivex.Single
fun <T> singleBuilder(builder: (callback: MatrixCallback<T>) -> Cancelable): Single<T> = Single.create { fun <T> singleBuilder(builder: (MatrixCallback<T>) -> Cancelable): Single<T> = Single.create { emitter ->
val callback: MatrixCallback<T> = object : MatrixCallback<T> { val callback = object : MatrixCallback<T> {
override fun onSuccess(data: T) { override fun onSuccess(data: T) {
it.onSuccess(data) // Add `!!` to fix the warning:
// "Type mismatch: type parameter with nullable bounds is used T is used where T was expected. This warning will become an error soon"
emitter.onSuccess(data!!)
} }
override fun onFailure(failure: Throwable) { override fun onFailure(failure: Throwable) {
it.tryOnError(failure) emitter.tryOnError(failure)
} }
} }
val cancelable = builder(callback) val cancelable = builder(callback)
it.setCancellable { emitter.setCancellable {
cancelable.cancel() cancelable.cancel()
} }
} }
fun <T> completableBuilder(builder: (callback: MatrixCallback<T>) -> Cancelable): Completable = Completable.create { fun <T> completableBuilder(builder: (MatrixCallback<T>) -> Cancelable): Completable = Completable.create { emitter ->
val callback: MatrixCallback<T> = object : MatrixCallback<T> { val callback = object : MatrixCallback<T> {
override fun onSuccess(data: T) { override fun onSuccess(data: T) {
it.onComplete() emitter.onComplete()
} }
override fun onFailure(failure: Throwable) { override fun onFailure(failure: Throwable) {
it.tryOnError(failure) emitter.tryOnError(failure)
} }
} }
val cancelable = builder(callback) val cancelable = builder(callback)
it.setCancellable { emitter.setCancellable {
cancelable.cancel() cancelable.cancel()
} }
} }

View file

@ -125,7 +125,6 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
implementation "androidx.appcompat:appcompat:1.2.0" implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.core:core-ktx:1.3.2" implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
@ -146,7 +145,7 @@ dependencies {
implementation "ru.noties.markwon:core:$markwon_version" implementation "ru.noties.markwon:core:$markwon_version"
// Image // Image
implementation 'androidx.exifinterface:exifinterface:1.3.0' implementation 'androidx.exifinterface:exifinterface:1.3.1'
// Database // Database
implementation 'com.github.Zhuinden:realm-monarchy:0.7.1' implementation 'com.github.Zhuinden:realm-monarchy:0.7.1'

View file

@ -31,6 +31,7 @@ import org.matrix.android.sdk.internal.extensions.toUnsignedInt
import org.matrix.olm.OlmSAS import org.matrix.olm.OlmSAS
import org.matrix.olm.OlmUtility import org.matrix.olm.OlmUtility
import timber.log.Timber import timber.log.Timber
import java.util.Locale
/** /**
* Represents an ongoing short code interactive key verification between two devices. * Represents an ongoing short code interactive key verification between two devices.
@ -344,7 +345,7 @@ internal abstract class SASDefaultVerificationTransaction(
} }
protected fun hashUsingAgreedHashMethod(toHash: String): String? { protected fun hashUsingAgreedHashMethod(toHash: String): String? {
if ("sha256".toLowerCase() == accepted?.hash?.toLowerCase()) { if ("sha256" == accepted?.hash?.toLowerCase(Locale.ROOT)) {
val olmUtil = OlmUtility() val olmUtil = OlmUtility()
val hashBytes = olmUtil.sha256(toHash) val hashBytes = olmUtil.sha256(toHash)
olmUtil.releaseUtility() olmUtil.releaseUtility()
@ -354,12 +355,11 @@ internal abstract class SASDefaultVerificationTransaction(
} }
private fun macUsingAgreedMethod(message: String, info: String): String? { private fun macUsingAgreedMethod(message: String, info: String): String? {
if (SAS_MAC_SHA256_LONGKDF.toLowerCase() == accepted?.messageAuthenticationCode?.toLowerCase()) { return when (accepted?.messageAuthenticationCode?.toLowerCase(Locale.ROOT)) {
return getSAS().calculateMacLongKdf(message, info) SAS_MAC_SHA256_LONGKDF -> getSAS().calculateMacLongKdf(message, info)
} else if (SAS_MAC_SHA256.toLowerCase() == accepted?.messageAuthenticationCode?.toLowerCase()) { SAS_MAC_SHA256 -> getSAS().calculateMac(message, info)
return getSAS().calculateMac(message, info) else -> null
} }
return null
} }
override fun getDecimalCodeRepresentation(): String { override fun getDecimalCodeRepresentation(): String {

View file

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.util package org.matrix.android.sdk.internal.util
import java.security.MessageDigest import java.security.MessageDigest
import java.util.Locale
/** /**
* Compute a Hash of a String, using md5 algorithm * Compute a Hash of a String, using md5 algorithm
@ -26,7 +27,7 @@ fun String.md5() = try {
digest.update(toByteArray()) digest.update(toByteArray())
digest.digest() digest.digest()
.joinToString("") { String.format("%02X", it) } .joinToString("") { String.format("%02X", it) }
.toLowerCase() .toLowerCase(Locale.ROOT)
} catch (exc: Exception) { } catch (exc: Exception) {
// Should not happen, but just in case // Should not happen, but just in case
hashCode().toString() hashCode().toString()

View file

@ -43,8 +43,8 @@ android {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01" implementation "androidx.fragment:fragment-ktx:1.3.0-beta01"
implementation 'androidx.exifinterface:exifinterface:1.3.0' implementation 'androidx.exifinterface:exifinterface:1.3.1'
// Log // Log
implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.jakewharton.timber:timber:4.7.1'

View file

@ -315,9 +315,8 @@ dependencies {
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha06" implementation "androidx.recyclerview:recyclerview:1.2.0-alpha06"
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:$fragment_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version" implementation "androidx.fragment:fragment-ktx:$fragment_version"
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.sharetarget:sharetarget:1.0.0" implementation "androidx.sharetarget:sharetarget:1.0.0"
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
@ -362,11 +361,11 @@ dependencies {
implementation "io.arrow-kt:arrow-core:$arrow_version" implementation "io.arrow-kt:arrow-core:$arrow_version"
// Pref // Pref
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference-ktx:1.1.1'
// UI // UI
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'com.google.android.material:material:1.3.0-alpha02' implementation 'com.google.android.material:material:1.3.0-alpha04'
implementation 'me.gujun.android:span:1.7' implementation 'me.gujun.android:span:1.7'
implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:core:$markwon_version"
implementation "io.noties.markwon:html:$markwon_version" implementation "io.noties.markwon:html:$markwon_version"
@ -374,7 +373,7 @@ dependencies {
implementation 'me.saket:better-link-movement-method:2.2.0' implementation 'me.saket:better-link-movement-method:2.2.0'
implementation 'com.google.android:flexbox:1.1.1' implementation 'com.google.android:flexbox:1.1.1'
implementation "androidx.autofill:autofill:$autofill_version" implementation "androidx.autofill:autofill:$autofill_version"
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta10' implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
// Custom Tab // Custom Tab
implementation 'androidx.browser:browser:1.2.0' implementation 'androidx.browser:browser:1.2.0'
@ -418,7 +417,7 @@ dependencies {
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.0' kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.0'
// gplay flavor only // gplay flavor only
gplayImplementation('com.google.firebase:firebase-messaging:20.3.0') { gplayImplementation('com.google.firebase:firebase-messaging:21.0.0') {
exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'

View file

@ -41,6 +41,7 @@
<issue id="ObsoleteSdkInt" severity="error" /> <issue id="ObsoleteSdkInt" severity="error" />
<issue id="Recycle" severity="error" /> <issue id="Recycle" severity="error" />
<issue id="KotlinPropertyAccess" severity="error" /> <issue id="KotlinPropertyAccess" severity="error" />
<issue id="DefaultLocale" severity="error" />
<issue id="InvalidPackage"> <issue id="InvalidPackage">
<!-- Ignore error from HtmlCompressor lib --> <!-- Ignore error from HtmlCompressor lib -->
@ -52,6 +53,9 @@
<!-- Manifest --> <!-- Manifest -->
<issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" /> <issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" />
<!-- Dependencies -->
<issue id="KtxExtensionAvailable" severity="error" />
<!-- Timber --> <!-- Timber -->
<!-- This rule is failing on CI because it's marked as unknwown rule id :/--> <!-- This rule is failing on CI because it's marked as unknwown rule id :/-->
<!-- <issue id="BinaryOperationInTimber" severity="error" />--> <!-- <issue id="BinaryOperationInTimber" severity="error" />-->

View file

@ -18,7 +18,7 @@ package im.vector.app.gplay.features.settings.troubleshoot
import android.content.Intent import android.content.Intent
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.iid.FirebaseInstanceId import com.google.firebase.messaging.FirebaseMessaging
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.startAddGoogleAccountIntent import im.vector.app.core.utils.startAddGoogleAccountIntent
@ -36,29 +36,33 @@ class TestFirebaseToken @Inject constructor(private val context: AppCompatActivi
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) { override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
status = TestStatus.RUNNING status = TestStatus.RUNNING
try { try {
FirebaseInstanceId.getInstance().instanceId FirebaseMessaging.getInstance().token
.addOnCompleteListener(context) { task -> .addOnCompleteListener(context) { task ->
if (!task.isSuccessful) { if (!task.isSuccessful) {
val errorMsg = if (task.exception == null) "Unknown" else task.exception!!.localizedMessage
// Can't find where this constant is (not documented -or deprecated in docs- and all obfuscated) // Can't find where this constant is (not documented -or deprecated in docs- and all obfuscated)
if ("SERVICE_NOT_AVAILABLE".equals(errorMsg)) { description = when (val errorMsg = task.exception?.localizedMessage ?: "Unknown") {
description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_service_not_available, errorMsg) "SERVICE_NOT_AVAILABLE" -> {
} else if ("TOO_MANY_REGISTRATIONS".equals(errorMsg)) { stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_service_not_available, errorMsg)
description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_too_many_registration, errorMsg) }
} else if ("ACCOUNT_MISSING".equals(errorMsg)) { "TOO_MANY_REGISTRATIONS" -> {
description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_account_missing, errorMsg) stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_too_many_registration, errorMsg)
}
"ACCOUNT_MISSING" -> {
quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_fcm_failed_account_missing_quick_fix) { quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_fcm_failed_account_missing_quick_fix) {
override fun doFix() { override fun doFix() {
startAddGoogleAccountIntent(context, activityResultLauncher) startAddGoogleAccountIntent(context, activityResultLauncher)
} }
} }
} else { stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed_account_missing, errorMsg)
description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed, errorMsg) }
else -> {
stringProvider.getString(R.string.settings_troubleshoot_test_fcm_failed, errorMsg)
}
} }
status = TestStatus.FAILED status = TestStatus.FAILED
} else { } else {
task.result?.token?.let { token -> task.result?.let { token ->
val tok = token.substring(0, Math.min(8, token.length)) + "********************" val tok = token.take(8) + "********************"
description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_success, tok) description = stringProvider.getString(R.string.settings_troubleshoot_test_fcm_success, tok)
Timber.e("Retrieved FCM token success [$tok].") Timber.e("Retrieved FCM token success [$tok].")
// Ensure it is well store in our local storage // Ensure it is well store in our local storage

View file

@ -21,7 +21,7 @@ import android.widget.Toast
import androidx.core.content.edit import androidx.core.content.edit
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.GoogleApiAvailability
import com.google.firebase.iid.FirebaseInstanceId import com.google.firebase.messaging.FirebaseMessaging
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.DefaultSharedPreferences import im.vector.app.core.di.DefaultSharedPreferences
@ -71,14 +71,16 @@ object FcmHelper {
// 'app should always check the device for a compatible Google Play services APK before accessing Google Play services features' // 'app should always check the device for a compatible Google Play services APK before accessing Google Play services features'
if (checkPlayServices(activity)) { if (checkPlayServices(activity)) {
try { try {
FirebaseInstanceId.getInstance().instanceId FirebaseMessaging.getInstance().token
.addOnSuccessListener(activity) { instanceIdResult -> .addOnSuccessListener { token ->
storeFcmToken(activity, instanceIdResult.token) storeFcmToken(activity, token)
if (registerPusher) { if (registerPusher) {
pushersManager.registerPusherWithFcmKey(instanceIdResult.token) pushersManager.registerPusherWithFcmKey(token)
} }
} }
.addOnFailureListener(activity) { e -> Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed") } .addOnFailureListener { e ->
Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed")
}
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed") Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed")
} }

View file

@ -21,6 +21,7 @@ import android.net.Uri
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import im.vector.app.core.utils.getFileExtension import im.vector.app.core.utils.getFileExtension
import timber.log.Timber import timber.log.Timber
import java.util.Locale
/** /**
* Returns the mimetype from a uri. * Returns the mimetype from a uri.
@ -44,7 +45,7 @@ fun getMimeTypeFromUri(context: Context, uri: Uri): String? {
if (null != mimeType) { if (null != mimeType) {
// the mimetype is sometimes in uppercase. // the mimetype is sometimes in uppercase.
mimeType = mimeType.toLowerCase() mimeType = mimeType.toLowerCase(Locale.ROOT)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "Failed to open resource input stream") Timber.e(e, "Failed to open resource input stream")

View file

@ -43,7 +43,7 @@ abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : V
* so you can use this in a switchMap or a flatMap * so you can use this in a switchMap or a flatMap
*/ */
// False positive // False positive
@Suppress("USELESS_CAST") @Suppress("USELESS_CAST", "NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER")
fun <T> Single<T>.toAsync(stateReducer: S.(Async<T>) -> S): Single<Async<T>> { fun <T> Single<T>.toAsync(stateReducer: S.(Async<T>) -> S): Single<Async<T>> {
setState { stateReducer(Loading()) } setState { stateReducer(Loading()) }
return map { Success(it) as Async<T> } return map { Success(it) as Async<T> }
@ -56,7 +56,7 @@ abstract class VectorViewModel<S : MvRxState, VA : VectorViewModelAction, VE : V
* so you can use this in a switchMap or a flatMap * so you can use this in a switchMap or a flatMap
*/ */
// False positive // False positive
@Suppress("USELESS_CAST") @Suppress("USELESS_CAST", "NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER")
fun <T> Observable<T>.toAsync(stateReducer: S.(Async<T>) -> S): Observable<Async<T>> { fun <T> Observable<T>.toAsync(stateReducer: S.(Async<T>) -> S): Observable<Async<T>> {
setState { stateReducer(Loading()) } setState { stateReducer(Loading()) }
return map { Success(it) as Async<T> } return map { Success(it) as Async<T> }

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.ui.bottomsheet
import com.airbnb.mvrx.MvRxState
import im.vector.app.core.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
abstract class BottomSheetGenericViewModel<State : MvRxState>(initialState: State) :
VectorViewModel<State, EmptyAction, EmptyViewEvents>(initialState) {
override fun handle(action: EmptyAction) {
// No op
}
}

View file

@ -44,7 +44,7 @@ open class BehaviorDataSource<T>(private val defaultValue: T? = null) : MutableD
} }
override fun post(value: T) { override fun post(value: T) {
behaviorRelay.accept(value) behaviorRelay.accept(value!!)
} }
private fun createRelay(): BehaviorRelay<T> { private fun createRelay(): BehaviorRelay<T> {
@ -68,6 +68,6 @@ open class PublishDataSource<T> : MutableDataSource<T> {
} }
override fun post(value: T) { override fun post(value: T) {
publishRelay.accept(value) publishRelay.accept(value!!)
} }
} }

View file

@ -19,6 +19,7 @@ package im.vector.app.core.utils
import android.content.Context import android.content.Context
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.util.Locale
// Implementation should return true in case of success // Implementation should return true in case of success
typealias ActionOnFile = (file: File) -> Boolean typealias ActionOnFile = (file: File) -> Boolean
@ -113,7 +114,7 @@ fun getFileExtension(fileUri: String): String? {
val ext = filename.substring(dotPos + 1) val ext = filename.substring(dotPos + 1)
if (ext.isNotBlank()) { if (ext.isNotBlank()) {
return ext.toLowerCase() return ext.toLowerCase(Locale.ROOT)
} }
} }
} }

View file

@ -59,7 +59,6 @@ data class AttachmentsPreviewArgs(
) : Parcelable ) : Parcelable
class AttachmentsPreviewFragment @Inject constructor( class AttachmentsPreviewFragment @Inject constructor(
val viewModelFactory: AttachmentsPreviewViewModel.Factory,
private val attachmentMiniaturePreviewController: AttachmentMiniaturePreviewController, private val attachmentMiniaturePreviewController: AttachmentMiniaturePreviewController,
private val attachmentBigPreviewController: AttachmentBigPreviewController, private val attachmentBigPreviewController: AttachmentBigPreviewController,
private val colorProvider: ColorProvider private val colorProvider: ColorProvider

View file

@ -17,31 +17,12 @@
package im.vector.app.features.attachments.preview package im.vector.app.features.attachments.preview
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
class AttachmentsPreviewViewModel @AssistedInject constructor(@Assisted initialState: AttachmentsPreviewViewState) class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState)
: VectorViewModel<AttachmentsPreviewViewState, AttachmentsPreviewAction, AttachmentsPreviewViewEvents>(initialState) { : VectorViewModel<AttachmentsPreviewViewState, AttachmentsPreviewAction, AttachmentsPreviewViewEvents>(initialState) {
@AssistedInject.Factory
interface Factory {
fun create(initialState: AttachmentsPreviewViewState): AttachmentsPreviewViewModel
}
companion object : MvRxViewModelFactory<AttachmentsPreviewViewModel, AttachmentsPreviewViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: AttachmentsPreviewViewState): AttachmentsPreviewViewModel? {
val fragment: AttachmentsPreviewFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.viewModelFactory.create(state)
}
}
override fun handle(action: AttachmentsPreviewAction) { override fun handle(action: AttachmentsPreviewAction) {
when (action) { when (action) {
is AttachmentsPreviewAction.SetCurrentAttachment -> handleSetCurrentAttachment(action) is AttachmentsPreviewAction.SetCurrentAttachment -> handleSetCurrentAttachment(action)

View file

@ -74,6 +74,10 @@ class PinFragment @Inject constructor(
Toast.makeText(requireContext(), getString(R.string.create_pin_confirm_failure), Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), getString(R.string.create_pin_confirm_failure), Toast.LENGTH_SHORT).show()
} }
override fun onPinCodeEnteredFirst(pinCode: String?): Boolean {
return false
}
override fun onCodeCreated(encodedCode: String) { override fun onCodeCreated(encodedCode: String) {
lifecycleScope.launch { lifecycleScope.launch {
pinCodeStore.storeEncodedPin(encodedCode) pinCodeStore.storeEncodedPin(encodedCode)

View file

@ -37,7 +37,6 @@ class RoomHistoryVisibilityBottomSheet : BottomSheetGeneric<RoomHistoryVisibilit
private lateinit var roomHistoryVisibilitySharedActionViewModel: RoomHistoryVisibilitySharedActionViewModel private lateinit var roomHistoryVisibilitySharedActionViewModel: RoomHistoryVisibilitySharedActionViewModel
@Inject lateinit var controller: RoomHistoryVisibilityController @Inject lateinit var controller: RoomHistoryVisibilityController
@Inject lateinit var roomHistoryVisibilityViewModelFactory: RoomHistoryVisibilityViewModel.Factory
private val viewModel: RoomHistoryVisibilityViewModel by fragmentViewModel(RoomHistoryVisibilityViewModel::class) private val viewModel: RoomHistoryVisibilityViewModel by fragmentViewModel(RoomHistoryVisibilityViewModel::class)
override fun injectWith(injector: ScreenComponent) { override fun injectWith(injector: ScreenComponent) {

View file

@ -16,32 +16,7 @@
package im.vector.app.features.roomprofile.settings.historyvisibility package im.vector.app.features.roomprofile.settings.historyvisibility
import com.airbnb.mvrx.FragmentViewModelContext import im.vector.app.core.ui.bottomsheet.BottomSheetGenericViewModel
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.app.core.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
class RoomHistoryVisibilityViewModel @AssistedInject constructor(@Assisted initialState: RoomHistoryVisibilityState) class RoomHistoryVisibilityViewModel(initialState: RoomHistoryVisibilityState)
: VectorViewModel<RoomHistoryVisibilityState, EmptyAction, EmptyViewEvents>(initialState) { : BottomSheetGenericViewModel<RoomHistoryVisibilityState>(initialState)
@AssistedInject.Factory
interface Factory {
fun create(initialState: RoomHistoryVisibilityState): RoomHistoryVisibilityViewModel
}
companion object : MvRxViewModelFactory<RoomHistoryVisibilityViewModel, RoomHistoryVisibilityState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomHistoryVisibilityState): RoomHistoryVisibilityViewModel? {
val fragment: RoomHistoryVisibilityBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.roomHistoryVisibilityViewModelFactory.create(state)
}
}
override fun handle(action: EmptyAction) {
// No op
}
}

View file

@ -39,7 +39,6 @@ class RoomJoinRuleBottomSheet : BottomSheetGeneric<RoomJoinRuleState, RoomJoinRu
private lateinit var roomJoinRuleSharedActionViewModel: RoomJoinRuleSharedActionViewModel private lateinit var roomJoinRuleSharedActionViewModel: RoomJoinRuleSharedActionViewModel
@Inject lateinit var controller: RoomJoinRuleController @Inject lateinit var controller: RoomJoinRuleController
@Inject lateinit var roomJoinRuleViewModelFactory: RoomJoinRuleViewModel.Factory
private val viewModel: RoomJoinRuleViewModel by fragmentViewModel(RoomJoinRuleViewModel::class) private val viewModel: RoomJoinRuleViewModel by fragmentViewModel(RoomJoinRuleViewModel::class)
override fun injectWith(injector: ScreenComponent) { override fun injectWith(injector: ScreenComponent) {

View file

@ -16,32 +16,7 @@
package im.vector.app.features.roomprofile.settings.joinrule package im.vector.app.features.roomprofile.settings.joinrule
import com.airbnb.mvrx.FragmentViewModelContext import im.vector.app.core.ui.bottomsheet.BottomSheetGenericViewModel
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.app.core.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
class RoomJoinRuleViewModel @AssistedInject constructor(@Assisted initialState: RoomJoinRuleState) class RoomJoinRuleViewModel(initialState: RoomJoinRuleState)
: VectorViewModel<RoomJoinRuleState, EmptyAction, EmptyViewEvents>(initialState) { : BottomSheetGenericViewModel<RoomJoinRuleState>(initialState)
@AssistedInject.Factory
interface Factory {
fun create(initialState: RoomJoinRuleState): RoomJoinRuleViewModel
}
companion object : MvRxViewModelFactory<RoomJoinRuleViewModel, RoomJoinRuleState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomJoinRuleState): RoomJoinRuleViewModel? {
val fragment: RoomJoinRuleBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.roomJoinRuleViewModelFactory.create(state)
}
}
override fun handle(action: EmptyAction) {
// No op
}
}