{
- runBlocking { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
+ runTest { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
}
}
}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/space/DefaultResolveSpaceInfoTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/space/DefaultResolveSpaceInfoTaskTest.kt
index f80c0f06d0..7203f89629 100644
--- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/space/DefaultResolveSpaceInfoTaskTest.kt
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/space/DefaultResolveSpaceInfoTaskTest.kt
@@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.session.space
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
import okhttp3.ResponseBody.Companion.toResponseBody
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
@@ -35,7 +35,7 @@ internal class DefaultResolveSpaceInfoTaskTest {
private val resolveSpaceInfoTask = DefaultResolveSpaceInfoTask(spaceApi.instance, globalErrorReceiver)
@Test
- fun `given stable endpoint works, when execute, then return stable api data`() = runBlockingTest {
+ fun `given stable endpoint works, when execute, then return stable api data`() = runTest {
spaceApi.givenStableEndpointReturns(response)
val result = resolveSpaceInfoTask.execute(spaceApi.params)
@@ -44,7 +44,7 @@ internal class DefaultResolveSpaceInfoTaskTest {
}
@Test
- fun `given stable endpoint fails, when execute, then fallback to unstable endpoint`() = runBlockingTest {
+ fun `given stable endpoint fails, when execute, then fallback to unstable endpoint`() = runTest {
spaceApi.givenStableEndpointThrows(httpException)
spaceApi.givenUnstableEndpointReturns(response)
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt
index 0abca8bee3..149b964fd2 100644
--- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt
@@ -21,7 +21,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.matrix.android.sdk.MatrixTest
@@ -51,7 +51,7 @@ class CoroutineSequencersTest : MatrixTest {
.also { results.add(it) }
}
)
- runBlocking {
+ runTest {
jobs.joinAll()
}
assertEquals(3, results.size)
@@ -81,7 +81,7 @@ class CoroutineSequencersTest : MatrixTest {
.also { results.add(it) }
}
)
- runBlocking {
+ runTest {
jobs.joinAll()
}
assertEquals(3, results.size)
@@ -109,7 +109,7 @@ class CoroutineSequencersTest : MatrixTest {
)
// We are canceling the second job
jobs[1].cancel()
- runBlocking {
+ runTest {
jobs.joinAll()
}
assertEquals(2, results.size)
diff --git a/tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl
index 64e6a0f83f..62b1f40df5 100644
--- a/tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl
+++ b/tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl
@@ -7,7 +7,6 @@ import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dagger.assisted.AssistedFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
<#if createViewEvents>
@@ -42,6 +41,6 @@ class ${viewModelClass} @AssistedInject constructor(@Assisted initialState: ${vi
override fun handle(action: ${actionClass}) {
when (action) {
- }.exhaustive
+ }
}
}
diff --git a/vector-config/src/main/res/values/config-settings.xml b/vector-config/src/main/res/values/config-settings.xml
index 0121ee9ae7..40fc68bbae 100755
--- a/vector-config/src/main/res/values/config-settings.xml
+++ b/vector-config/src/main/res/values/config-settings.xml
@@ -36,8 +36,9 @@
+ false
-
+
diff --git a/vector/build.gradle b/vector/build.gradle
index aeaad19e02..9f8471bc18 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -18,7 +18,7 @@ ext.versionMinor = 4
// Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release.
-ext.versionPatch = 6
+ext.versionPatch = 8
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'
@@ -411,7 +411,6 @@ dependencies {
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
implementation 'com.github.hyuwah:DraggableView:1.0.0'
- implementation 'com.github.Armen101:AudioRecordView:1.0.5'
// Custom Tab
implementation 'androidx.browser:browser:1.4.0'
diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt
index b3bb5172e8..d051488ad7 100644
--- a/vector/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt
+++ b/vector/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt
@@ -21,6 +21,7 @@ import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.matcher.ViewMatchers.isRoot
import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
import com.adevinta.android.barista.assertion.BaristaEnabledAssertions.assertDisabled
import com.adevinta.android.barista.assertion.BaristaEnabledAssertions.assertEnabled
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed
@@ -55,6 +56,8 @@ class OnboardingRobot {
fun createAccount(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") {
initSession(true, userId, password, homeServerUrl)
+ waitUntilViewVisible(withText(R.string.ftue_account_created_congratulations_title))
+ clickOn(R.string.ftue_account_created_take_me_home)
}
fun login(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
index 03e416813a..e007e61c1c 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.store.AnalyticsStore
@@ -53,7 +52,7 @@ class DebugAnalyticsViewModel @AssistedInject constructor(
override fun handle(action: DebugAnalyticsViewActions) {
when (action) {
DebugAnalyticsViewActions.ResetAnalyticsOptInDisplayed -> handleResetAnalyticsOptInDisplayed()
- }.exhaustive
+ }
}
private fun handleResetAnalyticsOptInDisplayed() {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt b/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
index 62871023bc..e469dbacda 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.debug.features.DebugVectorOverrides
@@ -71,7 +70,7 @@ class DebugPrivateSettingsViewModel @AssistedInject constructor(
is DebugPrivateSettingsViewActions.SetForceLoginFallbackEnabled -> handleSetForceLoginFallbackEnabled(action)
is SetDisplayNameCapabilityOverride -> handSetDisplayNameCapabilityOverride(action)
is SetAvatarCapabilityOverride -> handSetAvatarCapabilityOverride(action)
- }.exhaustive
+ }
}
private fun handleSetDialPadVisibility(action: DebugPrivateSettingsViewActions.SetDialPadVisibility) {
diff --git a/vector/src/main/assets/open_source_licenses.html b/vector/src/main/assets/open_source_licenses.html
index 2c25606f57..0bead1f826 100755
--- a/vector/src/main/assets/open_source_licenses.html
+++ b/vector/src/main/assets/open_source_licenses.html
@@ -437,11 +437,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2017-present, dialog LLC <info@dlg.im>
-
- Armen101 / AudioRecordView
-
- Copyright 2019 Armen Gevorgyan
-
Apache License
diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
index e3a84f95de..fdd6e3c2ba 100644
--- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
@@ -46,6 +46,7 @@ import im.vector.app.features.navigation.Navigator
import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.SharedPrefPinCodeStore
import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider
+import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
import im.vector.app.features.ui.UiStateRepository
import kotlinx.coroutines.CoroutineScope
@@ -113,10 +114,13 @@ object VectorStaticModule {
}
@Provides
- fun providesMatrixConfiguration(vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
+ fun providesMatrixConfiguration(
+ vectorPreferences: VectorPreferences,
+ vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
return MatrixConfiguration(
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider,
+ threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(),
presenceSyncEnabled = BuildConfig.PRESENCE_SYNC_ENABLED
)
}
diff --git a/vector/src/main/java/im/vector/app/core/extensions/Exhaustive.kt b/vector/src/main/java/im/vector/app/core/extensions/Exhaustive.kt
deleted file mode 100644
index 158ea84f0c..0000000000
--- a/vector/src/main/java/im/vector/app/core/extensions/Exhaustive.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 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.extensions
-
-// Trick to ensure that when block is exhaustive
-val T.exhaustive: T get() = this
diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
index 2c161feb37..4796022856 100644
--- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
+++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
@@ -54,7 +54,6 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ActivityEntryPoint
import im.vector.app.core.dialogs.DialogLocker
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.observeNotNull
import im.vector.app.core.extensions.registerStartForActivityResult
@@ -267,7 +266,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver
is GlobalError.CertificateError ->
handleCertificateError(globalError)
GlobalError.ExpiredAccount -> Unit // TODO Handle account expiration
- }.exhaustive
+ }
}
private fun handleCertificateError(certificateError: GlobalError.CertificateError) {
diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt
index 1a7a79ed8c..78266cf5ee 100644
--- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt
+++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt
@@ -83,6 +83,7 @@ class PushRulePreference : VectorPreference {
NotificationIndex.NOISY -> {
radioGroup?.check(R.id.bingPreferenceRadioBingRuleNoisy)
}
+ null -> Unit
}
radioGroup?.setOnCheckedChangeListener { _, checkedId ->
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt
index 94c1ab6576..58a5666e94 100755
--- a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt
@@ -77,13 +77,10 @@ class KeysBackupBanner @JvmOverloads constructor(
override fun onClick(v: View?) {
when (state) {
- is State.Setup -> {
- delegate?.setupKeysBackup()
- }
+ is State.Setup -> delegate?.setupKeysBackup()
is State.Update,
- is State.Recover -> {
- delegate?.recoverKeysBackup()
- }
+ is State.Recover -> delegate?.recoverKeysBackup()
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt
index 1615e77902..5190bb21a8 100644
--- a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt
@@ -27,7 +27,6 @@ import androidx.core.text.italic
import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.error.ResourceLimitErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.databinding.ViewNotificationAreaBinding
import im.vector.app.features.themes.ThemeUtils
@@ -77,7 +76,7 @@ class NotificationAreaView @JvmOverloads constructor(
is State.UnsupportedAlgorithm -> renderUnsupportedAlgorithm(newState)
is State.Tombstone -> renderTombstone()
is State.ResourceLimitExceededError -> renderResourceLimitExceededError(newState)
- }.exhaustive
+ }
}
// PRIVATE METHODS ****************************************************************************************************************************************
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/PresenceStateImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/PresenceStateImageView.kt
index 301f8afdc9..82675e8c11 100644
--- a/vector/src/main/java/im/vector/app/core/ui/views/PresenceStateImageView.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/PresenceStateImageView.kt
@@ -49,6 +49,7 @@ class PresenceStateImageView @JvmOverloads constructor(
setImageResource(R.drawable.ic_presence_offline)
contentDescription = context.getString(R.string.a11y_presence_offline)
}
+ null -> Unit
}
}
}
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
index ac0b4408b2..713c177099 100644
--- a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
@@ -40,21 +40,21 @@ class ShieldImageView @JvmOverloads constructor(
isVisible = roomEncryptionTrustLevel != null
when (roomEncryptionTrustLevel) {
- RoomEncryptionTrustLevel.Default -> {
+ RoomEncryptionTrustLevel.Default -> {
contentDescription = context.getString(R.string.a11y_trust_level_default)
setImageResource(
if (borderLess) R.drawable.ic_shield_black_no_border
else R.drawable.ic_shield_black
)
}
- RoomEncryptionTrustLevel.Warning -> {
+ RoomEncryptionTrustLevel.Warning -> {
contentDescription = context.getString(R.string.a11y_trust_level_warning)
setImageResource(
if (borderLess) R.drawable.ic_shield_warning_no_border
else R.drawable.ic_shield_warning
)
}
- RoomEncryptionTrustLevel.Trusted -> {
+ RoomEncryptionTrustLevel.Trusted -> {
contentDescription = context.getString(R.string.a11y_trust_level_trusted)
setImageResource(
if (borderLess) R.drawable.ic_shield_trusted_no_border
@@ -65,6 +65,7 @@ class ShieldImageView @JvmOverloads constructor(
contentDescription = context.getString(R.string.a11y_trust_level_trusted)
setImageResource(R.drawable.ic_warning_badge)
}
+ null -> Unit
}
}
}
@@ -72,9 +73,9 @@ class ShieldImageView @JvmOverloads constructor(
@DrawableRes
fun RoomEncryptionTrustLevel.toDrawableRes(): Int {
return when (this) {
- RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_black
- RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
- RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
+ RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_black
+ RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
+ RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
RoomEncryptionTrustLevel.E2EWithUnsupportedAlgorithm -> R.drawable.ic_warning_badge
}
}
diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt
index 33b735551c..42bd2318b3 100644
--- a/vector/src/main/java/im/vector/app/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt
@@ -241,7 +241,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity
// We have a session.
// Check it can be opened
if (sessionHolder.getActiveSession().isOpenable) {
- HomeActivity.newIntent(this)
+ HomeActivity.newIntent(this, existingSession = true)
} else {
// The token is still invalid
navigator.softLogout(this)
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
index 2c7a8ac9bc..a570b31452 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.VectorAnalytics
import kotlinx.coroutines.launch
@@ -55,7 +54,7 @@ class AnalyticsConsentViewModel @AssistedInject constructor(
override fun handle(action: AnalyticsConsentViewActions) {
when (action) {
is AnalyticsConsentViewActions.SetUserConsent -> handleSetUserConsent(action)
- }.exhaustive
+ }
}
private fun handleSetUserConsent(action: AnalyticsConsentViewActions.SetUserConsent) {
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
index c84031d2fd..c11cf582d3 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
@@ -19,7 +19,6 @@ package im.vector.app.features.analytics.ui.consent
import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.ScreenOrientationLocker
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
@@ -48,7 +47,7 @@ class AnalyticsOptInActivity : VectorBaseActivity() {
viewModel.observeViewEvents {
when (it) {
AnalyticsOptInViewEvents.OnDataSaved -> finish()
- }.exhaustive
+ }
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt
index 0a0e700ce9..3e9d72e98b 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt
@@ -17,7 +17,6 @@
package im.vector.app.features.attachments.preview
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) :
@@ -28,7 +27,7 @@ class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) :
is AttachmentsPreviewAction.SetCurrentAttachment -> handleSetCurrentAttachment(action)
is AttachmentsPreviewAction.UpdatePathOfCurrentAttachment -> handleUpdatePathOfCurrentAttachment(action)
AttachmentsPreviewAction.RemoveCurrentAttachment -> handleRemoveCurrentAttachment()
- }.exhaustive
+ }
}
private fun handleRemoveCurrentAttachment() = withState {
diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt
index 8d30c4d5c5..b3fc36e5bc 100644
--- a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt
+++ b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt
@@ -111,6 +111,7 @@ class CallControlsView @JvmOverloads constructor(
views.ringingControls.isVisible = false
views.connectedControls.isVisible = false
}
+ null -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
index 23c7b79914..e9d16ee710 100644
--- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt
@@ -525,8 +525,7 @@ class VectorCallActivity : VectorBaseActivity(), CallContro
navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId)
}
is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
- null -> {
- }
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt
index a26eec04f3..449a740cf3 100644
--- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt
@@ -26,7 +26,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.call.audio.CallAudioManager
import im.vector.app.features.call.dialpad.DialPadLookup
@@ -343,7 +342,7 @@ class VectorCallViewModel @AssistedInject constructor(
setState { VectorCallViewState(action.callArgs) }
setupCallWithCurrentState()
}
- }.exhaustive
+ }
}
private fun handleCallTransfer() {
@@ -358,7 +357,7 @@ class VectorCallViewModel @AssistedInject constructor(
when (result) {
is CallTransferResult.ConnectWithUserId -> connectWithUserId(result)
is CallTransferResult.ConnectWithPhoneNumber -> connectWithPhoneNumber(result)
- }.exhaustive
+ }
}
private fun connectWithUserId(result: CallTransferResult.ConnectWithUserId) {
diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt
index d04bebfd1b..f0b7b75afb 100644
--- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt
@@ -27,7 +27,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@@ -103,7 +102,7 @@ class JitsiCallViewModel @AssistedInject constructor(
when (action) {
is JitsiCallViewActions.SwitchTo -> handleSwitchTo(action)
JitsiCallViewActions.OnConferenceLeft -> handleOnConferenceLeft()
- }.exhaustive
+ }
}
private fun handleSwitchTo(action: JitsiCallViewActions.SwitchTo) = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
index a668f66f30..5a12337e4f 100644
--- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt
@@ -35,7 +35,6 @@ import com.facebook.react.modules.core.PermissionListener
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityJitsiBinding
import kotlinx.parcelize.Parcelize
@@ -79,7 +78,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMee
JitsiCallViewEvents.FailJoiningConference -> handleFailJoining()
JitsiCallViewEvents.Finish -> finish()
JitsiCallViewEvents.LeaveConference -> handleLeaveConference()
- }.exhaustive
+ }
}
lifecycle.addObserver(ConferenceEventObserver(this, this::onBroadcastEvent))
}
diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
index d8eede6a55..b10353be13 100644
--- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt
@@ -26,7 +26,6 @@ import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityCallTransferBinding
import kotlinx.parcelize.Parcelize
@@ -57,7 +56,7 @@ class CallTransferActivity : VectorBaseActivity() {
callTransferViewModel.observeViewEvents {
when (it) {
is CallTransferViewEvents.Complete -> handleComplete()
- }.exhaustive
+ }
}
sectionsPagerAdapter = CallTransferPagerAdapter(this)
diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt
index ebd0089736..7425e0ae8a 100644
--- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.withState
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.showIdentityServerConsentDialog
@@ -73,7 +72,7 @@ class ContactsBookFragment @Inject constructor(
when (it) {
is ContactsBookViewEvents.Failure -> showFailure(it.throwable)
is ContactsBookViewEvents.OnPoliciesRetrieved -> showConsentDialog(it)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt
index 5678668b25..d016558764 100644
--- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt
@@ -27,7 +27,6 @@ import im.vector.app.core.contacts.ContactsDataSource
import im.vector.app.core.contacts.MappedContact
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.discovery.fetchIdentityServerWithTerms
@@ -165,7 +164,7 @@ class ContactsBookViewModel @AssistedInject constructor(
is ContactsBookAction.OnlyBoundContacts -> handleOnlyBoundContacts(action)
ContactsBookAction.UserConsentGranted -> handleUserConsentGranted()
ContactsBookAction.UserConsentRequest -> handleUserConsentRequest()
- }.exhaustive
+ }
}
private fun handleUserConsentRequest() {
diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt
index 9df4f52d0f..0d36c7c7cc 100644
--- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt
@@ -28,6 +28,7 @@ import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
@@ -35,7 +36,6 @@ import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.platform.WaitingViewData
import im.vector.app.core.utils.PERMISSIONS_FOR_MEMBERS_SEARCH
@@ -84,7 +84,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
is UserListSharedAction.OnMenuItemSelected -> onMenuItemSelected(action)
UserListSharedAction.OpenPhoneBook -> openPhoneBook()
UserListSharedAction.AddByQrCode -> openAddByQrCode()
- }.exhaustive
+ }
}
.launchIn(lifecycleScope)
if (isFirstCreation()) {
@@ -111,7 +111,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
Toast.makeText(this, R.string.cannot_dm_self, Toast.LENGTH_SHORT).show()
finish()
}
- }.exhaustive
+ }
}
qrViewModel.observeViewEvents {
@@ -124,7 +124,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
finish()
}
else -> Unit
- }.exhaustive
+ }
}
}
@@ -167,6 +167,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
private fun renderCreateAndInviteState(state: Async) {
when (state) {
+ Uninitialized,
is Loading -> renderCreationLoading()
is Success -> renderCreationSuccess(state())
is Fail -> renderCreationFailure(state.error)
diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
index 9dd3ef6a9b..d3011496d2 100644
--- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt
@@ -24,7 +24,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.raw.wellknown.getElementWellknown
@@ -56,7 +55,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
when (action) {
is CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers -> onSubmitInvitees(action.selections)
is CreateDirectRoomAction.QrScannedAction -> onCodeParsed(action)
- }.exhaustive
+ }
}
private fun onCodeParsed(action: CreateDirectRoomAction.QrScannedAction) {
@@ -108,7 +107,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
when (it) {
is PendingSelection.UserPendingSelection -> invitedUserIds.add(it.user.userId)
is PendingSelection.ThreePidPendingSelection -> invite3pids.add(it.threePid)
- }.exhaustive
+ }
}
setDirectMessage()
enableEncryptionIfInvitedUsersSupportIt = adminE2EByDefault
diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
index 577572ef14..3c922e6309 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
@@ -140,6 +140,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
isBackupAlreadySetup = true
}
+ null -> Unit
}
if (isBackupAlreadySetup) {
diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt
index b317ac95ad..0a105064d5 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt
@@ -116,12 +116,13 @@ class SharedSecureStorageActivity :
is SharedSecureStorageViewEvent.FinishSuccess -> {
val dataResult = Intent()
dataResult.putExtra(EXTRA_DATA_RESULT, it.cypherResult)
- setResult(Activity.RESULT_OK, dataResult)
+ setResult(RESULT_OK, dataResult)
finish()
}
is SharedSecureStorageViewEvent.ShowResetBottomSheet -> {
navigator.open4SSetup(this, SetupMode.HARD_RESET)
}
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
index 8994ad901b..d324a52242 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt
@@ -29,7 +29,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.platform.WaitingViewData
import im.vector.app.core.resources.StringProvider
@@ -142,7 +141,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
SharedSecureStorageAction.Back -> handleBack()
SharedSecureStorageAction.ForgotResetAll -> handleResetAll()
SharedSecureStorageAction.DoResetAll -> handleDoResetAll()
- }.exhaustive
+ }
}
private fun handleDoResetAll() {
diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt
index 8e7f11f0f5..fd660367ae 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt
@@ -77,6 +77,7 @@ class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment
is SharedSecureStorageViewEvent.KeyInlineError -> {
views.ssssKeyEnterTil.error = it.message
}
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
index 70c1003773..41507f2722 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt
@@ -86,6 +86,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor(
is SharedSecureStorageViewEvent.InlineError -> {
views.ssssPassphraseEnterTil.error = it.message
}
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
index 8448422a56..ac7662ca59 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
@@ -36,7 +36,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.commitTransaction
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
@@ -209,7 +208,7 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment Unit
}
return@withState
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
index 45f7f56957..2495ae4ea5 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
@@ -28,7 +28,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import kotlinx.coroutines.Dispatchers
@@ -365,7 +364,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
copy(verifyingFrom4S = false)
}
}
- }.exhaustive
+ }
}
private fun handleSecretBackFromSSSS(action: VerificationAction.GotResultFromSsss) {
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
index 6f213adb7e..aec28f898e 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
@@ -139,6 +139,7 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor(
)
}
}
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
index 90997830a0..781677433b 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
@@ -18,6 +18,7 @@ package im.vector.app.features.crypto.verification.request
import androidx.core.text.toSpannable
import com.airbnb.epoxy.EpoxyController
+import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
@@ -153,6 +154,7 @@ class VerificationRequestController @Inject constructor(
}
}
}
+ is Fail -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt
index 57d3ccc16b..f1f6142fa2 100644
--- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt
@@ -34,7 +34,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.resources.ColorProvider
@@ -79,7 +78,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
Unit
}
is DevToolsViewEvents.ShowSnackMessage -> showSnackbar(it.message)
- }.exhaustive
+ }
}
supportFragmentManager.addOnBackStackChangedListener(this)
}
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
index 551b72dd82..b338f367e3 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
@@ -50,6 +50,7 @@ class DiscoverySettingsController @Inject constructor(
override fun buildModels(data: DiscoverySettingsState) {
when (data.identityServer) {
+ Uninitialized,
is Loading -> {
loadingItem {
id("identityServerLoading")
@@ -209,18 +210,19 @@ class DiscoverySettingsController @Inject constructor(
titleResId(R.string.settings_discovery_emails_title)
}
when (emails) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("emailsLoading")
}
}
- is Fail -> {
+ is Fail -> {
settingsInfoItem {
id("emailsError")
helperText(emails.error.message)
}
}
- is Success -> {
+ is Success -> {
if (emails().isEmpty()) {
settingsInfoItem {
id("emailsEmpty")
@@ -277,18 +279,19 @@ class DiscoverySettingsController @Inject constructor(
}
when (msisdns) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("msisdnLoading")
}
}
- is Fail -> {
+ is Fail -> {
settingsInfoItem {
id("msisdnListError")
helperText(msisdns.error.message)
}
}
- is Success -> {
+ is Success -> {
if (msisdns().isEmpty()) {
settingsInfoItem {
id("no_msisdn")
@@ -353,6 +356,7 @@ class DiscoverySettingsController @Inject constructor(
colorProvider(host.colorProvider)
stringProvider(host.stringProvider)
when (pidInfo.isShared) {
+ Uninitialized,
is Loading -> {
buttonIndeterminate(true)
}
@@ -384,6 +388,7 @@ class DiscoverySettingsController @Inject constructor(
else -> iconMode(IconMode.NONE)
}
}
+ null -> Unit
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt
index 523e8cb9bb..2de03f296e 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt
@@ -28,7 +28,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment
@@ -70,7 +69,7 @@ class DiscoverySettingsFragment @Inject constructor(
when (it) {
is DiscoverySharedViewModelAction.ChangeIdentityServer ->
viewModel.handle(DiscoverySettingsAction.ChangeIdentityServer(it.newUrl))
- }.exhaustive
+ }
}
viewModel.observeViewEvents {
@@ -78,7 +77,7 @@ class DiscoverySettingsFragment @Inject constructor(
is DiscoverySettingsViewEvents.Failure -> {
displayErrorDialog(it.throwable)
}
- }.exhaustive
+ }
}
if (discoveryArgs.expandIdentityPolicies) {
viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = true))
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
index 19f233fe98..8c1caaf67a 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
@@ -27,7 +27,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import kotlinx.coroutines.flow.launchIn
@@ -113,7 +112,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
is DiscoverySettingsAction.FinalizeBind3pid -> finalizeBind3pid(action, true)
is DiscoverySettingsAction.SubmitMsisdnToken -> submitMsisdnToken(action)
is DiscoverySettingsAction.CancelBinding -> cancelBinding(action)
- }.exhaustive
+ }
}
private fun handleUpdateUserConsent(action: DiscoverySettingsAction.UpdateUserConsent) {
@@ -235,7 +234,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
when (action.threePid) {
is ThreePid.Email -> revokeEmail(action.threePid)
is ThreePid.Msisdn -> revokeMsisdn(action.threePid)
- }.exhaustive
+ }
}
private fun revokeEmail(threePid: ThreePid.Email) = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt b/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt
index 527d28dfad..29a44a1d8a 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/SettingsTextButtonSingleLineItem.kt
@@ -34,7 +34,6 @@ import im.vector.app.core.epoxy.attributes.ButtonStyle
import im.vector.app.core.epoxy.attributes.ButtonType
import im.vector.app.core.epoxy.attributes.IconMode
import im.vector.app.core.epoxy.onClick
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
@@ -122,7 +121,7 @@ abstract class SettingsTextButtonSingleLineItem : EpoxyModelWithHolder {
holder.mainButton.setTextColor(colorProvider.getColorFromAttribute(R.attr.colorError))
}
- }.exhaustive
+ }
holder.mainButton.onClick(buttonClickListener)
}
ButtonType.SWITCH -> {
@@ -133,7 +132,7 @@ abstract class SettingsTextButtonSingleLineItem : EpoxyModelWithHolder useDefault()
is SetIdentityServerAction.UseCustomIdentityServer -> usedCustomIdentityServerUrl(action)
- }.exhaustive
+ }
}
private fun useDefault() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
index 964fb6f365..009edcc69e 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
@@ -38,7 +38,6 @@ import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.AppStateHandler
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.replaceFragment
@@ -90,6 +89,7 @@ import javax.inject.Inject
data class HomeActivityArgs(
val clearNotification: Boolean,
val accountCreation: Boolean,
+ val hasExistingSession: Boolean = false,
val inviteNotificationRoomId: String? = null
) : Parcelable
@@ -106,6 +106,7 @@ class HomeActivity :
@Suppress("UNUSED")
private val analyticsAccountDataViewModel: AnalyticsAccountDataViewModel by viewModel()
+
@Suppress("UNUSED")
private val userColorAccountDataViewModel: UserColorAccountDataViewModel by viewModel()
@@ -231,7 +232,7 @@ class HomeActivity :
HomeActivitySharedAction.SendSpaceFeedBack -> {
bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
}
- }.exhaustive
+ }
}
.launchIn(lifecycleScope)
@@ -253,7 +254,9 @@ class HomeActivity :
HomeActivityViewEvents.PromptToEnableSessionPush -> handlePromptToEnablePush()
is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it)
HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn()
- }.exhaustive
+ HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
+ is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
+ }
}
homeActivityViewModel.onEach { renderState(it) }
@@ -269,6 +272,48 @@ class HomeActivity :
navigator.openAnalyticsOptIn(this)
}
+ /**
+ * Migrating from old threads io.element.thread to new m.thread needs an initial sync to
+ * sync and display existing messages appropriately
+ */
+ private fun migrateThreadsIfNeeded(checkSession: Boolean) {
+ if (checkSession) {
+ // We should check session to ensure we will only clear cache if needed
+ val args = intent.getParcelableExtra(Mavericks.KEY_ARG)
+ if (args?.hasExistingSession == true) {
+ // existingSession --> Will be true only if we came from an existing active session
+ Timber.i("----> Migrating threads from an existing session..")
+ handleThreadsMigration()
+ } else {
+ // We came from a new session and not an existing one,
+ // so there is no need to migrate threads while an initial synced performed
+ Timber.i("----> No thread migration needed, we are ok")
+ vectorPreferences.setShouldMigrateThreads(shouldMigrate = false)
+ }
+ } else {
+ // Proceed with migration
+ handleThreadsMigration()
+ }
+ }
+
+ /**
+ * Clear cache and restart to invoke an initial sync for threads migration
+ */
+ private fun handleThreadsMigration() {
+ Timber.i("----> Threads Migration detected, clearing cache and sync...")
+ vectorPreferences.setShouldMigrateThreads(shouldMigrate = false)
+ MainActivity.restartApp(this, MainActivityArgs(clearCache = true))
+ }
+
+ private fun handleNotifyUserForThreadsMigration() {
+ MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.threads_notice_migration_title)
+ .setMessage(R.string.threads_notice_migration_message)
+ .setCancelable(true)
+ .setPositiveButton(R.string.sas_got_it) { _, _ -> }
+ .show()
+ }
+
private fun handleIntent(intent: Intent?) {
intent?.dataString?.let { deepLink ->
val resolvedLink = when {
@@ -329,7 +374,7 @@ class HomeActivity :
// Idle or Incremental sync status
views.waitingView.root.isVisible = false
}
- }.exhaustive
+ }
}
private fun handleAskPasswordToInitCrossSigning(events: HomeActivityViewEvents.AskPasswordToInitCrossSigning) {
@@ -546,11 +591,13 @@ class HomeActivity :
fun newIntent(context: Context,
clearNotification: Boolean = false,
accountCreation: Boolean = false,
+ existingSession: Boolean = false,
inviteNotificationRoomId: String? = null
): Intent {
val args = HomeActivityArgs(
clearNotification = clearNotification,
accountCreation = accountCreation,
+ hasExistingSession = existingSession,
inviteNotificationRoomId = inviteNotificationRoomId
)
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt
index adc44a57bd..5efd49a579 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt
@@ -25,4 +25,6 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
object PromptToEnableSessionPush : HomeActivityViewEvents
object ShowAnalyticsOptIn : HomeActivityViewEvents
+ object NotifyUserForThreadsMigration : HomeActivityViewEvents
+ data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
}
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
index 35c112b63a..87de0a32e3 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
@@ -25,7 +25,6 @@ import im.vector.app.config.analyticsConfig
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.store.AnalyticsStore
import im.vector.app.features.login.ReAuthHelper
@@ -51,6 +50,7 @@ import org.matrix.android.sdk.api.util.toMatrixItem
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
+import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage
import org.matrix.android.sdk.internal.util.awaitCallback
import timber.log.Timber
import kotlin.coroutines.Continuation
@@ -62,6 +62,7 @@ class HomeActivityViewModel @AssistedInject constructor(
private val activeSessionHolder: ActiveSessionHolder,
private val reAuthHelper: ReAuthHelper,
private val analyticsStore: AnalyticsStore,
+ private val lightweightSettingsStorage: LightweightSettingsStorage,
private val vectorPreferences: VectorPreferences
) : VectorViewModel(initialState) {
@@ -84,6 +85,7 @@ class HomeActivityViewModel @AssistedInject constructor(
checkSessionPushIsOn()
observeCrossSigningReset()
observeAnalytics()
+ initThreadsMigration()
}
private fun observeAnalytics() {
@@ -130,6 +132,46 @@ class HomeActivityViewModel @AssistedInject constructor(
.launchIn(viewModelScope)
}
+ /**
+ * Handle threads migration. The migration includes:
+ * - Notify users that had io.element.thread enabled from labs
+ * - Re-Enable m.thread to those users (that they had enabled labs threads)
+ * - Handle migration when threads are enabled by default
+ */
+ private fun initThreadsMigration() {
+ // When we would like to enable threads for all users
+// if(vectorPreferences.shouldMigrateThreads()) {
+// vectorPreferences.setThreadMessagesEnabled()
+// lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
+// }
+
+ when {
+ // Notify users
+ vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.areThreadMessagesEnabled() -> {
+ Timber.i("----> Notify users about threads")
+ // Notify the user if needed that we migrated to support m.thread
+ // instead of io.element.thread so old thread messages will be displayed as normal timeline messages
+ _viewEvents.post(HomeActivityViewEvents.NotifyUserForThreadsMigration)
+ vectorPreferences.userNotifiedAboutThreads()
+ }
+ // Migrate users with enabled lab settings
+ vectorPreferences.shouldNotifyUserAboutThreads() && vectorPreferences.shouldMigrateThreads() -> {
+ Timber.i("----> Migrate threads with enabled labs")
+ // If user had io.element.thread enabled then enable the new thread support,
+ // clear cache to sync messages appropriately
+ vectorPreferences.setThreadMessagesEnabled()
+ lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
+ // Clear Cache
+ _viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = false))
+ }
+ // Enable all users
+ vectorPreferences.shouldMigrateThreads() && vectorPreferences.areThreadMessagesEnabled() -> {
+ Timber.i("----> Try to migrate threads")
+ _viewEvents.post(HomeActivityViewEvents.MigrateThreads(checkSession = true))
+ }
+ }
+ }
+
private fun observeInitialSync() {
val session = activeSessionHolder.getSafeActiveSession() ?: return
@@ -263,6 +305,6 @@ class HomeActivityViewModel @AssistedInject constructor(
HomeActivityViewActions.ViewStarted -> {
initialize()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt
index e812942996..01d91f3edc 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt
@@ -273,6 +273,7 @@ class HomeDetailViewModel @AssistedInject constructor(
)
}
}
+ null -> Unit
}
}
.launchIn(viewModelScope)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
index ebb07a3a90..587d3d3cc8 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
@@ -72,7 +72,6 @@ import im.vector.app.core.dialogs.ConfirmationDialogBuilder
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
import im.vector.app.core.extensions.cleanup
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide
@@ -447,7 +446,7 @@ class TimelineFragment @Inject constructor(
}
showErrorInSnackbar(it.throwable)
}
- }.exhaustive
+ }
}
timelineViewModel.observeViewEvents {
@@ -484,7 +483,7 @@ class TimelineFragment @Inject constructor(
RoomDetailViewEvents.StopChatEffects -> handleStopChatEffects()
is RoomDetailViewEvents.DisplayAndAcceptCall -> acceptIncomingCall(it)
RoomDetailViewEvents.RoomReplacementStarted -> handleRoomReplacement()
- }.exhaustive
+ }
}
if (savedInstanceState == null) {
@@ -785,6 +784,18 @@ class TimelineFragment @Inject constructor(
updateRecordingUiState(RecordingUiState.Draft)
}
+ override fun onVoiceWaveformTouchedUp(percentage: Float, duration: Int) {
+ messageComposerViewModel.handle(
+ MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage)
+ )
+ }
+
+ override fun onVoiceWaveformMoved(percentage: Float, duration: Int) {
+ messageComposerViewModel.handle(
+ MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage)
+ )
+ }
+
private fun updateRecordingUiState(state: RecordingUiState) {
messageComposerViewModel.handle(
MessageComposerAction.OnVoiceRecordingUiStateChanged(state))
@@ -876,7 +887,7 @@ class TimelineFragment @Inject constructor(
onContentAttachmentsReady(sharedData.attachmentData)
}
null -> Timber.v("No share data to process")
- }.exhaustive
+ }
}
private fun handleSpaceShare() {
@@ -1248,7 +1259,7 @@ class TimelineFragment @Inject constructor(
insertUserDisplayNameInTextEditor(roomDetailPendingAction.userId)
is RoomDetailPendingAction.OpenRoom ->
handleOpenRoom(RoomDetailViewEvents.OpenRoom(roomDetailPendingAction.roomId, roomDetailPendingAction.closeCurrentRoom))
- }.exhaustive
+ }
}
override fun onPause() {
@@ -1621,11 +1632,10 @@ class TimelineFragment @Inject constructor(
views.includeRoomToolbar.roomToolbarContentView.isClickable = roomSummary.membership == Membership.JOIN
views.includeRoomToolbar.roomToolbarTitleView.text = roomSummary.displayName
avatarRenderer.render(roomSummary.toMatrixItem(), views.includeRoomToolbar.roomToolbarAvatarImageView)
- views.includeRoomToolbar.roomToolbarDecorationImageView.render(roomSummary.roomEncryptionTrustLevel)
- views.includeRoomToolbar.roomToolbarPresenceImageView.render(
- roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled,
- roomSummary.directUserPresence
- )
+ val showPresence = roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled
+ views.includeRoomToolbar.roomToolbarPresenceImageView.render(showPresence, roomSummary.directUserPresence)
+ val shieldView = if (showPresence) views.includeRoomToolbar.roomToolbarTitleShield else views.includeRoomToolbar.roomToolbarAvatarShield
+ shieldView.render(roomSummary.roomEncryptionTrustLevel)
views.includeRoomToolbar.roomToolbarPublicImageView.isVisible = roomSummary.isPublic && !roomSummary.isDirect
}
} else {
@@ -1667,7 +1677,7 @@ class TimelineFragment @Inject constructor(
is MessageComposerViewEvents.SlashCommandNotSupportedInThreads -> {
displayCommandError(getString(R.string.command_not_supported_in_threads, sendMessageResult.command.command))
}
- } // .exhaustive
+ } //
lockSendButton = false
}
@@ -1791,6 +1801,7 @@ class TimelineFragment @Inject constructor(
transactionId = data.transactionId,
).show(parentFragmentManager, "REQ")
}
+ else -> Unit
}
}
@@ -2060,6 +2071,14 @@ class TimelineFragment @Inject constructor(
messageComposerViewModel.handle(MessageComposerAction.PlayOrPauseVoicePlayback(eventId, messageAudioContent))
}
+ override fun onVoiceWaveformTouchedUp(eventId: String, duration: Int, percentage: Float) {
+ messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformTouchedUp(eventId, duration, percentage))
+ }
+
+ override fun onVoiceWaveformMovedTo(eventId: String, duration: Int, percentage: Float) {
+ messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformMovedTo(eventId, duration, percentage))
+ }
+
private fun onShareActionClicked(action: EventSharedAction.Share) {
when (action.messageContent) {
is MessageTextContent -> shareText(requireContext(), action.messageContent.body)
@@ -2245,6 +2264,8 @@ class TimelineFragment @Inject constructor(
is EventSharedAction.EndPoll -> {
askConfirmationToEndPoll(action.eventId)
}
+ is EventSharedAction.ReportContent -> Unit /* Not clickable */
+ EventSharedAction.Separator -> Unit /* Not clickable */
}
}
@@ -2443,7 +2464,7 @@ class TimelineFragment @Inject constructor(
locationOwnerId = session.myUserId
)
}
- }.exhaustive
+ }
}
// AttachmentsHelper.Callback
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
index a9235b5699..6933adc758 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
@@ -33,7 +33,6 @@ import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -440,7 +439,7 @@ class TimelineViewModel @AssistedInject constructor(
_viewEvents.post(RoomDetailViewEvents.OpenRoom(action.replacementRoomId, closeCurrentRoom = true))
}
is RoomDetailAction.EndPoll -> handleEndPoll(action.eventId)
- }.exhaustive
+ }
}
private fun handleJitsiCallJoinStatus(action: RoomDetailAction.UpdateJoinJitsiCallStatus) = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt
index 10cef39942..091e9f7869 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt
@@ -40,4 +40,6 @@ sealed class MessageComposerAction : VectorViewModelAction {
data class PlayOrPauseVoicePlayback(val eventId: String, val messageAudioContent: MessageAudioContent) : MessageComposerAction()
object PlayOrPauseRecordingPlayback : MessageComposerAction()
data class EndAllVoiceActions(val deleteRecord: Boolean = true) : MessageComposerAction()
+ data class VoiceWaveformTouchedUp(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction()
+ data class VoiceWaveformMovedTo(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction()
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
index 009d898940..976489eec3 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.analytics.AnalyticsTracker
@@ -109,6 +108,8 @@ class MessageComposerViewModel @AssistedInject constructor(
is MessageComposerAction.EndAllVoiceActions -> handleEndAllVoiceActions(action.deleteRecord)
is MessageComposerAction.InitializeVoiceRecorder -> handleInitializeVoiceRecorder(action.attachmentData)
is MessageComposerAction.OnEntersBackground -> handleEntersBackground(action.composerText)
+ is MessageComposerAction.VoiceWaveformTouchedUp -> handleVoiceWaveformTouchedUp(action)
+ is MessageComposerAction.VoiceWaveformMovedTo -> handleVoiceWaveformMovedTo(action)
}
}
@@ -463,7 +464,7 @@ class MessageComposerViewModel @AssistedInject constructor(
_viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk())
popDraft()
}
- }.exhaustive
+ }
}
is SendMode.Edit -> {
// is original event a reply?
@@ -536,7 +537,7 @@ class MessageComposerViewModel @AssistedInject constructor(
is SendMode.Voice -> {
// do nothing
}
- }.exhaustive
+ }
}
}
@@ -869,12 +870,23 @@ class MessageComposerViewModel @AssistedInject constructor(
voiceMessageHelper.pauseRecording()
}
+ private fun handleVoiceWaveformTouchedUp(action: MessageComposerAction.VoiceWaveformTouchedUp) {
+ voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration)
+ }
+
+ private fun handleVoiceWaveformMovedTo(action: MessageComposerAction.VoiceWaveformMovedTo) {
+ voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration)
+ }
+
private fun handleEntersBackground(composerText: String) {
+ // Always stop all voice actions. It may be playing in timeline or active recording
+ val playingAudioContent = voiceMessageHelper.stopAllVoiceActions(deleteRecord = false)
+ voiceMessageHelper.clearTracker()
+
val isVoiceRecording = com.airbnb.mvrx.withState(this) { it.isVoiceRecording }
if (isVoiceRecording) {
- voiceMessageHelper.clearTracker()
viewModelScope.launch {
- voiceMessageHelper.stopAllVoiceActions(deleteRecord = false)?.toContentAttachmentData()?.let { voiceDraft ->
+ playingAudioContent?.toContentAttachmentData()?.let { voiceDraft ->
val content = voiceDraft.toJsonString()
room.saveDraft(UserDraft.Voice(content))
setState { copy(sendMode = SendMode.Voice(content)) }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt
index bede7a3ce7..3d263a9a97 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt
@@ -132,9 +132,11 @@ class VoiceMessageHelper @Inject constructor(
}
fun startOrPausePlayback(id: String, file: File) {
- stopPlayback()
+ val playbackState = playbackTracker.getPlaybackState(id)
+ mediaPlayer?.stop()
+ stopPlaybackTicker()
stopRecordingAmplitudes()
- if (playbackTracker.getPlaybackState(id) is AudioMessagePlaybackTracker.Listener.State.Playing) {
+ if (playbackState is AudioMessagePlaybackTracker.Listener.State.Playing) {
playbackTracker.pausePlayback(id)
} else {
startPlayback(id, file)
@@ -169,11 +171,19 @@ class VoiceMessageHelper @Inject constructor(
}
fun stopPlayback() {
- playbackTracker.stopPlayback(AudioMessagePlaybackTracker.RECORDING_ID)
+ playbackTracker.pausePlayback(AudioMessagePlaybackTracker.RECORDING_ID)
mediaPlayer?.stop()
stopPlaybackTicker()
}
+ fun movePlaybackTo(id: String, percentage: Float, totalDuration: Int) {
+ val toMillisecond = (totalDuration * percentage).toInt()
+ playbackTracker.updateCurrentPlaybackTime(id, toMillisecond, percentage)
+
+ stopPlayback()
+ playbackTracker.pausePlayback(id)
+ }
+
private fun startRecordingAmplitudes() {
amplitudeTicker?.stop()
amplitudeTicker = CountUpTimer(50).apply {
@@ -221,7 +231,9 @@ class VoiceMessageHelper @Inject constructor(
private fun onPlaybackTick(id: String) {
if (mediaPlayer?.isPlaying.orFalse()) {
val currentPosition = mediaPlayer?.currentPosition ?: 0
- playbackTracker.updateCurrentPlaybackTime(id, currentPosition)
+ val totalDuration = mediaPlayer?.duration ?: 0
+ val percentage = currentPosition.toFloat() / totalDuration
+ playbackTracker.updateCurrentPlaybackTime(id, currentPosition, percentage)
} else {
playbackTracker.stopPlayback(id)
stopPlaybackTicker()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
index a9f6e33d50..b898aaf114 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
@@ -23,7 +23,6 @@ import androidx.constraintlayout.widget.ConstraintLayout
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.BuildConfig
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.hardware.vibrate
import im.vector.app.core.time.Clock
import im.vector.app.core.utils.DimensionConverter
@@ -53,6 +52,8 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
fun onDeleteVoiceMessage()
fun onRecordingLimitReached()
fun onRecordingWaveformClicked()
+ fun onVoiceWaveformTouchedUp(percentage: Float, duration: Int)
+ fun onVoiceWaveformMoved(percentage: Float, duration: Int)
}
@Inject lateinit var clock: Clock
@@ -65,6 +66,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private var recordingTicker: CountUpTimer? = null
private var lastKnownState: RecordingUiState? = null
private var dragState: DraggingState = DraggingState.Ignored
+ private var recordingDuration: Long = 0
init {
inflate(this.context, R.layout.view_voice_message_recorder, this)
@@ -95,9 +97,9 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
override fun onDeleteVoiceMessage() = callback.onDeleteVoiceMessage()
override fun onWaveformClicked() {
when (lastKnownState) {
- RecordingUiState.Draft -> callback.onVoicePlaybackButtonClicked()
is RecordingUiState.Recording,
is RecordingUiState.Locked -> callback.onRecordingWaveformClicked()
+ else -> Unit
}
}
@@ -105,6 +107,18 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
override fun onMicButtonDrag(nextDragStateCreator: (DraggingState) -> DraggingState) {
onDrag(dragState, newDragState = nextDragStateCreator(dragState))
}
+
+ override fun onVoiceWaveformTouchedUp(percentage: Float) {
+ if (lastKnownState == RecordingUiState.Draft) {
+ callback.onVoiceWaveformTouchedUp(percentage, recordingDuration.toInt())
+ }
+ }
+
+ override fun onVoiceWaveformMoved(percentage: Float) {
+ if (lastKnownState == RecordingUiState.Draft) {
+ callback.onVoiceWaveformMoved(percentage, recordingDuration.toInt())
+ }
+ }
})
}
@@ -119,7 +133,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
fun render(recordingState: RecordingUiState) {
if (lastKnownState == recordingState) return
when (recordingState) {
- RecordingUiState.Idle -> {
+ RecordingUiState.Idle -> {
reset()
}
is RecordingUiState.Recording -> {
@@ -137,7 +151,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
voiceMessageViews.showRecordingLockedViews(recordingState)
}, 500)
}
- RecordingUiState.Draft -> {
+ RecordingUiState.Draft -> {
stopRecordingTicker()
voiceMessageViews.showDraftViews()
}
@@ -167,7 +181,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
DraggingState.Ready -> {
// do nothing
}
- }.exhaustive
+ }
dragState = newDragState
}
@@ -203,6 +217,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
}
private fun stopRecordingTicker() {
+ recordingDuration = recordingTicker?.elapsedTime() ?: 0
recordingTicker?.stop()
recordingTicker = null
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt
index 5070785569..0256064af2 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt
@@ -27,7 +27,6 @@ import androidx.core.view.doOnLayout
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
-import com.visualizer.amplitude.AudioRecordView
import im.vector.app.R
import im.vector.app.core.extensions.setAttributeBackground
import im.vector.app.core.extensions.setAttributeTintedBackground
@@ -37,6 +36,8 @@ import im.vector.app.databinding.ViewVoiceMessageRecorderBinding
import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView.DraggingState
import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView.RecordingUiState
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
+import im.vector.app.features.themes.ThemeUtils
+import im.vector.app.features.voice.AudioWaveformView
class VoiceMessageViews(
private val resources: Resources,
@@ -59,8 +60,21 @@ class VoiceMessageViews(
actions.onDeleteVoiceMessage()
}
- views.voicePlaybackWaveform.setOnClickListener {
- actions.onWaveformClicked()
+ views.voicePlaybackWaveform.setOnTouchListener { view, motionEvent ->
+ when (motionEvent.action) {
+ MotionEvent.ACTION_DOWN -> {
+ actions.onWaveformClicked()
+ }
+ MotionEvent.ACTION_UP -> {
+ val percentage = getTouchedPositionPercentage(motionEvent, view)
+ actions.onVoiceWaveformTouchedUp(percentage)
+ }
+ MotionEvent.ACTION_MOVE -> {
+ val percentage = getTouchedPositionPercentage(motionEvent, view)
+ actions.onVoiceWaveformMoved(percentage)
+ }
+ }
+ true
}
views.voicePlaybackControlButton.setOnClickListener {
@@ -69,6 +83,8 @@ class VoiceMessageViews(
observeMicButton(actions)
}
+ private fun getTouchedPositionPercentage(motionEvent: MotionEvent, view: View) = (motionEvent.x / view.width).coerceIn(0f, 1f)
+
@SuppressLint("ClickableViewAccessibility")
private fun observeMicButton(actions: Actions) {
val draggableStateProcessor = DraggableStateProcessor(resources, dimensionConverter)
@@ -284,7 +300,7 @@ class VoiceMessageViews(
hideRecordingViews(RecordingUiState.Idle)
views.voiceMessageMicButton.isVisible = true
views.voiceMessageSendButton.isVisible = false
- views.voicePlaybackWaveform.post { views.voicePlaybackWaveform.recreate() }
+ views.voicePlaybackWaveform.post { views.voicePlaybackWaveform.clear() }
}
fun renderPlaying(state: AudioMessagePlaybackTracker.Listener.State.Playing) {
@@ -292,11 +308,15 @@ class VoiceMessageViews(
views.voicePlaybackControlButton.contentDescription = resources.getString(R.string.a11y_pause_voice_message)
val formattedTimerText = DateUtils.formatElapsedTime((state.playbackTime / 1000).toLong())
views.voicePlaybackTime.text = formattedTimerText
+ val waveformColorIdle = ThemeUtils.getColor(views.voicePlaybackWaveform.context, R.attr.vctr_content_quaternary)
+ val waveformColorPlayed = ThemeUtils.getColor(views.voicePlaybackWaveform.context, R.attr.vctr_content_secondary)
+ views.voicePlaybackWaveform.updateColors(state.percentage, waveformColorPlayed, waveformColorIdle)
}
fun renderIdle() {
views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play)
views.voicePlaybackControlButton.contentDescription = resources.getString(R.string.a11y_play_voice_message)
+ views.voicePlaybackWaveform.summarize()
}
fun renderToast(message: String) {
@@ -327,8 +347,9 @@ class VoiceMessageViews(
fun renderRecordingWaveform(amplitudeList: Array) {
views.voicePlaybackWaveform.doOnLayout { waveFormView ->
+ val waveformColor = ThemeUtils.getColor(waveFormView.context, R.attr.vctr_content_quaternary)
amplitudeList.iterator().forEach {
- (waveFormView as AudioRecordView).update(it)
+ (waveFormView as AudioWaveformView).add(AudioWaveformView.FFT(it.toFloat(), waveformColor))
}
}
}
@@ -349,5 +370,7 @@ class VoiceMessageViews(
fun onDeleteVoiceMessage()
fun onWaveformClicked()
fun onVoicePlaybackButtonClicked()
+ fun onVoiceWaveformTouchedUp(percentage: Float)
+ fun onVoiceWaveformMoved(percentage: Float)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt
index 62c142238e..fbcf29d863 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt
@@ -26,6 +26,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
@@ -88,6 +89,7 @@ class SearchFragment @Inject constructor(
override fun invalidate() = withState(searchViewModel) { state ->
if (state.searchResult.isNullOrEmpty()) {
when (state.asyncSearchRequest) {
+ Uninitialized,
is Loading -> {
views.stateView.state = StateView.State.Loading
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt
index 7bff76cc36..1702fb95cd 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job
@@ -56,7 +55,7 @@ class SearchViewModel @AssistedInject constructor(
is SearchAction.SearchWith -> handleSearchWith(action)
is SearchAction.LoadMore -> handleLoadMore()
is SearchAction.Retry -> handleRetry()
- }.exhaustive
+ }
}
private fun handleSearchWith(action: SearchAction.SearchWith) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
index a14888362b..023c28cdc7 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
@@ -145,6 +145,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
fun getPreviewUrlRetriever(): PreviewUrlRetriever
fun onVoiceControlButtonClicked(eventId: String, messageAudioContent: MessageAudioContent)
+ fun onVoiceWaveformTouchedUp(eventId: String, duration: Int, percentage: Float)
+ fun onVoiceWaveformMovedTo(eventId: String, duration: Int, percentage: Float)
fun onAddMoreReaction(event: TimelineEvent)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
index 1dad6cc4a7..9f05547300 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
@@ -18,8 +18,9 @@ package im.vector.app.features.home.room.detail.timeline.edithistory
import android.text.Spannable
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
@@ -54,18 +55,19 @@ class ViewEditHistoryEpoxyController @Inject constructor(
override fun buildModels(state: ViewEditHistoryViewState) {
val host = this
when (state.editList) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
genericLoaderItem {
id("Spinner")
}
}
- is Fail -> {
+ is Fail -> {
genericFooterItem {
id("failure")
text(host.stringProvider.getString(R.string.unknown_error).toEpoxyCharSequence())
}
}
- is Success -> {
+ is Success -> {
state.editList()?.let { renderEvents(it, state.isOriginalAReply) }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index 1b352b93e1..745f04b159 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -76,6 +76,7 @@ import im.vector.app.features.location.toLocationData
import im.vector.app.features.media.ImageContentRenderer
import im.vector.app.features.media.VideoContentRenderer
import im.vector.app.features.settings.VectorPreferences
+import im.vector.app.features.voice.AudioWaveformView
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
import me.gujun.android.span.span
import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl
@@ -358,11 +359,24 @@ class MessageItemFactory @Inject constructor(
val fileUrl = getAudioFileUrl(messageContent, informationData)
val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params)
+ val waveformTouchListener: MessageVoiceItem.WaveformTouchListener = object : MessageVoiceItem.WaveformTouchListener {
+ override fun onWaveformTouchedUp(percentage: Float) {
+ val duration = messageContent.audioInfo?.duration ?: 0
+ params.callback?.onVoiceWaveformTouchedUp(informationData.eventId, duration, percentage)
+ }
+
+ override fun onWaveformMovedTo(percentage: Float) {
+ val duration = messageContent.audioInfo?.duration ?: 0
+ params.callback?.onVoiceWaveformMovedTo(informationData.eventId, duration, percentage)
+ }
+ }
+
return MessageVoiceItem_()
.attributes(attributes)
.duration(messageContent.audioWaveformInfo?.duration ?: 0)
.waveform(messageContent.audioWaveformInfo?.waveform?.toFft().orEmpty())
.playbackControlButtonClickListener(playbackControlButtonClickListener)
+ .waveformTouchListener(waveformTouchListener)
.voiceMessagePlaybackTracker(audioMessagePlaybackTracker)
.isLocalFile(localFilesHelper.isLocalFile(fileUrl))
.mxcUrl(fileUrl)
@@ -698,8 +712,8 @@ class MessageItemFactory @Inject constructor(
return this
?.filterNotNull()
?.map {
- // Value comes from AudioRecordView.maxReportableAmp, and 1024 is the max value in the Matrix spec
- it * 22760 / 1024
+ // Value comes from AudioWaveformView.MAX_FFT, and 1024 is the max value in the Matrix spec
+ it * AudioWaveformView.MAX_FFT / 1024
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt
index 774b0d797e..7404735e28 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt
@@ -70,7 +70,8 @@ class AudioMessagePlaybackTracker @Inject constructor() {
fun startPlayback(id: String) {
val currentPlaybackTime = getPlaybackTime(id)
- val currentState = Listener.State.Playing(currentPlaybackTime)
+ val currentPercentage = getPercentage(id)
+ val currentState = Listener.State.Playing(currentPlaybackTime, currentPercentage)
setState(id, currentState)
// Pause any active playback
states
@@ -87,15 +88,16 @@ class AudioMessagePlaybackTracker @Inject constructor() {
fun pausePlayback(id: String) {
val currentPlaybackTime = getPlaybackTime(id)
- setState(id, Listener.State.Paused(currentPlaybackTime))
+ val currentPercentage = getPercentage(id)
+ setState(id, Listener.State.Paused(currentPlaybackTime, currentPercentage))
}
fun stopPlayback(id: String) {
setState(id, Listener.State.Idle)
}
- fun updateCurrentPlaybackTime(id: String, time: Int) {
- setState(id, Listener.State.Playing(time))
+ fun updateCurrentPlaybackTime(id: String, time: Int, percentage: Float) {
+ setState(id, Listener.State.Playing(time, percentage))
}
fun updateCurrentRecording(id: String, amplitudeList: List) {
@@ -113,6 +115,15 @@ class AudioMessagePlaybackTracker @Inject constructor() {
}
}
+ private fun getPercentage(id: String): Float {
+ return when (val state = states[id]) {
+ is Listener.State.Playing -> state.percentage
+ is Listener.State.Paused -> state.percentage
+ /* Listener.State.Idle, */
+ else -> 0f
+ }
+ }
+
fun clear() {
listeners.forEach {
it.value.onUpdate(Listener.State.Idle)
@@ -131,8 +142,8 @@ class AudioMessagePlaybackTracker @Inject constructor() {
sealed class State {
object Idle : State()
- data class Playing(val playbackTime: Int) : State()
- data class Paused(val playbackTime: Int) : State()
+ data class Playing(val playbackTime: Int, val percentage: Float) : State()
+ data class Paused(val playbackTime: Int, val percentage: Float) : State()
data class Recording(val amplitudeList: List) : State()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
index 0909cbe8de..9ff8ddfbce 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
@@ -26,7 +26,6 @@ import dagger.hilt.android.scopes.ActivityScoped
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.utils.TextUtils
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
@@ -86,7 +85,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
is ContentUploadStateTracker.State.Success -> handleSuccess()
is ContentUploadStateTracker.State.CompressingImage -> handleCompressingImage()
is ContentUploadStateTracker.State.CompressingVideo -> handleCompressingVideo(state)
- }.exhaustive
+ }
}
private fun handleIdle() {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
index 70d93e4263..f82504595d 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
@@ -19,14 +19,15 @@ package im.vector.app.features.home.room.detail.timeline.item
import android.content.res.ColorStateList
import android.graphics.Color
import android.text.format.DateUtils
+import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
+import androidx.core.view.doOnLayout
import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
-import com.visualizer.amplitude.AudioRecordView
import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
@@ -34,10 +35,16 @@ import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadSt
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
import im.vector.app.features.themes.ThemeUtils
+import im.vector.app.features.voice.AudioWaveformView
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class MessageVoiceItem : AbsMessageItem() {
+ interface WaveformTouchListener {
+ fun onWaveformTouchedUp(percentage: Float)
+ fun onWaveformMovedTo(percentage: Float)
+ }
+
@EpoxyAttribute
var mxcUrl: String = ""
@@ -64,6 +71,9 @@ abstract class MessageVoiceItem : AbsMessageItem() {
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var playbackControlButtonClickListener: ClickListener? = null
+ @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
+ var waveformTouchListener: WaveformTouchListener? = null
+
@EpoxyAttribute
lateinit var voiceMessagePlaybackTracker: AudioMessagePlaybackTracker
@@ -78,13 +88,8 @@ abstract class MessageVoiceItem : AbsMessageItem() {
holder.progressLayout.isVisible = false
}
- holder.voicePlaybackWaveform.setOnLongClickListener(attributes.itemLongClickListener)
-
- holder.voicePlaybackWaveform.post {
- holder.voicePlaybackWaveform.recreate()
- waveform.forEach { amplitude ->
- holder.voicePlaybackWaveform.update(amplitude)
- }
+ holder.voicePlaybackWaveform.doOnLayout {
+ onWaveformViewReady(holder)
}
val backgroundTint = if (attributes.informationData.messageLayout is TimelineMessageLayout.Bubble) {
@@ -94,6 +99,33 @@ abstract class MessageVoiceItem : AbsMessageItem() {
}
holder.voicePlaybackLayout.backgroundTintList = ColorStateList.valueOf(backgroundTint)
holder.voicePlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) }
+ }
+
+ private fun onWaveformViewReady(holder: Holder) {
+ holder.voicePlaybackWaveform.setOnLongClickListener(attributes.itemLongClickListener)
+
+ val waveformColorIdle = ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_quaternary)
+ val waveformColorPlayed = ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_secondary)
+
+ holder.voicePlaybackWaveform.clear()
+ waveform.forEach { amplitude ->
+ holder.voicePlaybackWaveform.add(AudioWaveformView.FFT(amplitude.toFloat(), waveformColorIdle))
+ }
+ holder.voicePlaybackWaveform.summarize()
+
+ holder.voicePlaybackWaveform.setOnTouchListener { view, motionEvent ->
+ when (motionEvent.action) {
+ MotionEvent.ACTION_UP -> {
+ val percentage = getTouchedPositionPercentage(motionEvent, view)
+ waveformTouchListener?.onWaveformTouchedUp(percentage)
+ }
+ MotionEvent.ACTION_MOVE -> {
+ val percentage = getTouchedPositionPercentage(motionEvent, view)
+ waveformTouchListener?.onWaveformMovedTo(percentage)
+ }
+ }
+ true
+ }
voiceMessagePlaybackTracker.track(attributes.informationData.eventId, object : AudioMessagePlaybackTracker.Listener {
override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) {
@@ -101,27 +133,33 @@ abstract class MessageVoiceItem : AbsMessageItem() {
is AudioMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder)
is AudioMessagePlaybackTracker.Listener.State.Playing -> renderPlayingState(holder, state)
is AudioMessagePlaybackTracker.Listener.State.Paused -> renderPausedState(holder, state)
+ is AudioMessagePlaybackTracker.Listener.State.Recording -> Unit
}
}
})
}
- private fun renderIdleState(holder: Holder) {
+ private fun getTouchedPositionPercentage(motionEvent: MotionEvent, view: View) = (motionEvent.x / view.width).coerceIn(0f, 1f)
+
+ private fun renderIdleState(holder: Holder, idleColor: Int, playedColor: Int) {
holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play)
holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_play_voice_message)
holder.voicePlaybackTime.text = formatPlaybackTime(duration)
+ holder.voicePlaybackWaveform.updateColors(0f, playedColor, idleColor)
}
- private fun renderPlayingState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Playing) {
+ private fun renderPlayingState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Playing, idleColor: Int, playedColor: Int) {
holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause)
holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_pause_voice_message)
holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime)
+ holder.voicePlaybackWaveform.updateColors(state.percentage, playedColor, idleColor)
}
- private fun renderPausedState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Paused) {
+ private fun renderPausedState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Paused, idleColor: Int, playedColor: Int) {
holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play)
holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_play_voice_message)
holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime)
+ holder.voicePlaybackWaveform.updateColors(state.percentage, playedColor, idleColor)
}
private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong())
@@ -140,7 +178,7 @@ abstract class MessageVoiceItem : AbsMessageItem() {
val voiceLayout by bind(R.id.voiceLayout)
val voicePlaybackControlButton by bind(R.id.voicePlaybackControlButton)
val voicePlaybackTime by bind(R.id.voicePlaybackTime)
- val voicePlaybackWaveform by bind(R.id.voicePlaybackWaveform)
+ val voicePlaybackWaveform by bind(R.id.voicePlaybackWaveform)
val progressLayout by bind(R.id.messageFileUploadProgressLayout)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollOptionView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollOptionView.kt
index 2be933d9c3..80daa595b6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollOptionView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollOptionView.kt
@@ -23,7 +23,6 @@ import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.setAttributeTintedImageResource
import im.vector.app.databinding.ItemPollOptionBinding
@@ -49,7 +48,7 @@ class PollOptionView @JvmOverloads constructor(
is PollOptionViewState.PollReady -> renderPollReady()
is PollOptionViewState.PollVoted -> renderPollVoted(state)
is PollOptionViewState.PollUndisclosed -> renderPollUndisclosed(state)
- }.exhaustive
+ }
}
private fun renderPollSending() {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt
index 821531416b..61fcddd123 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt
@@ -31,7 +31,6 @@ import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
@@ -105,7 +104,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem {
+ Uninitialized,
+ is Loading -> {
genericLoaderItem {
id("Spinner")
}
}
- is Fail -> {
+ is Fail -> {
genericFooterItem {
id("failure")
text(host.stringProvider.getString(R.string.unknown_error).toEpoxyCharSequence())
}
}
- is Success -> {
+ is Success -> {
state.mapReactionKeyToMemberList()?.forEach { reactionInfo ->
reactionInfoSimpleItem {
id(reactionInfo.eventId)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
index 4265eebe62..18389b551f 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
@@ -38,7 +38,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
import im.vector.app.core.extensions.cleanup
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.StateView
import im.vector.app.core.platform.VectorBaseFragment
@@ -128,7 +127,7 @@ class RoomListFragment @Inject constructor(
is RoomListViewEvents.SelectRoom -> handleSelectRoom(it, it.isInviteAlreadyAccepted)
is RoomListViewEvents.Done -> Unit
is RoomListViewEvents.NavigateToMxToBottomSheet -> handleShowMxToLink(it.link)
- }.exhaustive
+ }
}
views.createChatFabMenu.listener = this
@@ -418,7 +417,7 @@ class RoomListFragment @Inject constructor(
is RoomListQuickActionsSharedAction.Leave -> {
promptLeaveRoom(quickAction.roomId)
}
- }.exhaustive
+ }
}
private fun promptLeaveRoom(roomId: String) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt
index ec8b01876b..70974bc1f6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt
@@ -29,7 +29,6 @@ import im.vector.app.AppStateHandler
import im.vector.app.RoomGroupingMethod
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.analytics.AnalyticsTracker
@@ -163,7 +162,7 @@ class RoomListViewModel @AssistedInject constructor(
is RoomListAction.ToggleSection -> handleToggleSection(action.section)
is RoomListAction.JoinSuggestedRoom -> handleJoinSuggestedRoom(action)
is RoomListAction.ShowRoomDetails -> handleShowRoomDetails(action)
- }.exhaustive
+ }
}
fun isPublicRoom(roomId: String): Boolean {
diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt
index 48a70fb164..7bb6670e96 100644
--- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt
@@ -74,8 +74,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
is UserListSharedAction.OnMenuItemSelected -> onMenuItemSelected(sharedAction)
UserListSharedAction.OpenPhoneBook -> openPhoneBook()
// not exhaustive because it's a sharedAction
- else -> {
- }
+ else -> Unit
}
}
.launchIn(lifecycleScope)
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
index c4dccc1b73..d61d53ae51 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
@@ -29,7 +29,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.mapbox.mapboxsdk.maps.MapView
import im.vector.app.BuildConfig
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING
import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING
@@ -86,7 +85,7 @@ class LocationSharingFragment @Inject constructor(
LocationSharingViewEvents.Close -> locationSharingNavigator.quit()
LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
index 639666e63f..1d68247f2c 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
import im.vector.app.features.location.domain.usecase.CompareLocationsUseCase
@@ -122,7 +121,7 @@ class LocationSharingViewModel @AssistedInject constructor(
is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action)
LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction()
LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction()
- }.exhaustive
+ }
}
private fun handleCurrentUserLocationSharingAction() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt
index 8b83873142..f5e48e84e7 100644
--- a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
import kotlinx.coroutines.CancellationException
@@ -69,7 +68,7 @@ abstract class AbstractLoginFragment : VectorBaseFragment(
else ->
// This is handled by the Activity
Unit
- }.exhaustive
+ }
}
override fun showFailure(throwable: Throwable) {
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
index a40f26acec..dec6fef040 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt
@@ -35,7 +35,6 @@ import im.vector.app.R
import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.validateBackPressed
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityLoginBinding
@@ -197,7 +196,7 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA
is LoginViewEvents.Loading ->
// This is handled by the Fragments
Unit
- }.exhaustive
+ }
}
private fun updateWithState(loginViewState: LoginViewState) {
@@ -260,13 +259,13 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA
tag = FRAGMENT_LOGIN_TAG,
option = commonOption)
LoginMode.Unsupported -> onLoginModeNotSupported(state.loginModeSupportedTypes)
- }.exhaustive
+ }
}
SignMode.SignInWithMatrixId -> addFragmentToBackstack(views.loginFragmentContainer,
LoginFragment::class.java,
tag = FRAGMENT_LOGIN_TAG,
option = commonOption)
- }.exhaustive
+ }
}
/**
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt
index da61d95997..22f8792078 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt
@@ -29,8 +29,8 @@ import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.hidePassword
import im.vector.app.core.extensions.toReducedUrl
@@ -97,7 +97,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment SocialLoginButtonsView.Mode.MODE_SIGN_UP
SignMode.SignIn,
SignMode.SignInWithMatrixId -> SocialLoginButtonsView.Mode.MODE_SIGN_IN
- }.exhaustive
+ }
}
private fun submit() {
@@ -269,6 +269,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment {
// Ensure password is hidden
views.passwordField.hidePassword()
@@ -300,7 +301,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment Unit
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt
index d121245532..1d32944f9f 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt
@@ -23,7 +23,6 @@ import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
-import com.airbnb.mvrx.Success
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.hideKeyboard
@@ -129,7 +128,7 @@ class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment {
views.resetPasswordEmailTil.error = errorFormatter.toHumanReadable(state.asyncResetPassword.error)
}
- is Success -> Unit
+ else -> Unit
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt
index 5f376700f8..232e7ab622 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt
@@ -21,7 +21,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Success
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.databinding.FragmentLoginResetPasswordMailConfirmationBinding
@@ -59,7 +58,7 @@ class LoginResetPasswordMailConfirmationFragment @Inject constructor() : Abstrac
setupUi(state)
when (state.asyncResetMailConfirmed) {
- is Fail -> {
+ is Fail -> {
// Link in email not yet clicked ?
val message = if (state.asyncResetMailConfirmed.error.is401()) {
getString(R.string.auth_reset_password_error_unauthorized)
@@ -73,7 +72,7 @@ class LoginResetPasswordMailConfirmationFragment @Inject constructor() : Abstrac
.setPositiveButton(R.string.ok, null)
.show()
}
- is Success -> Unit
+ else -> Unit
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt
index bfa924c155..246c3ad464 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt
@@ -31,7 +31,6 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.configureAndStart
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.ensureTrailingSlash
@@ -131,7 +130,7 @@ class LoginViewModel @AssistedInject constructor(
is LoginAction.UserAcceptCertificate -> handleUserAcceptCertificate(action)
LoginAction.ClearHomeServerHistory -> handleClearHomeServerHistory()
is LoginAction.PostViewEvent -> _viewEvents.post(action.viewEvent)
- }.exhaustive
+ }
}
private fun handleOnGetStarted(action: LoginAction.OnGetStarted) {
@@ -173,6 +172,7 @@ class LoginViewModel @AssistedInject constructor(
.withAllowedFingerPrints(listOf(action.fingerprint))
.build()
)
+ else -> Unit
}
}
@@ -447,7 +447,7 @@ class LoginViewModel @AssistedInject constructor(
handle(LoginAction.UpdateHomeServer(matrixOrgUrl))
ServerType.EMS,
ServerType.Other -> _viewEvents.post(LoginViewEvents.OnServerSelectionDone(action.serverType))
- }.exhaustive
+ }
}
private fun handleInitWith(action: LoginAction.InitWith) {
@@ -555,7 +555,7 @@ class LoginViewModel @AssistedInject constructor(
SignMode.SignIn -> handleLogin(action)
SignMode.SignUp -> handleRegisterWith(action)
SignMode.SignInWithMatrixId -> handleDirectLogin(action, null)
- }.exhaustive
+ }
}
private fun handleDirectLogin(action: LoginAction.LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?) {
@@ -585,7 +585,7 @@ class LoginViewModel @AssistedInject constructor(
else -> {
onWellKnownError()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/login2/AbstractLoginFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/AbstractLoginFragment2.kt
index 8c9749d91e..68568d1420 100644
--- a/vector/src/main/java/im/vector/app/features/login2/AbstractLoginFragment2.kt
+++ b/vector/src/main/java/im/vector/app/features/login2/AbstractLoginFragment2.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
import kotlinx.coroutines.CancellationException
@@ -67,7 +66,7 @@ abstract class AbstractLoginFragment2 : VectorBaseFragment
else ->
// This is handled by the Activity
Unit
- }.exhaustive
+ }
}
override fun showFailure(throwable: Throwable) {
diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt
index b73988126b..8125c6e089 100644
--- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt
+++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt
@@ -18,7 +18,6 @@ package im.vector.app.features.login2
import android.content.Context
import android.net.Uri
-import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
@@ -29,7 +28,6 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.configureAndStart
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.tryAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -137,7 +135,7 @@ class LoginViewModel2 @AssistedInject constructor(
LoginAction2.ClearHomeServerHistory -> handleClearHomeServerHistory()
is LoginAction2.PostViewEvent -> _viewEvents.post(action.viewEvent)
is LoginAction2.Finish -> handleFinish()
- }.exhaustive
+ }
}
private fun handleFinish() {
@@ -172,6 +170,7 @@ class LoginViewModel2 @AssistedInject constructor(
handleSetUserPassword(finalLastAction)
is LoginAction2.LoginWith ->
handleLoginWith(finalLastAction)
+ else -> Unit
}
}
@@ -500,7 +499,7 @@ class LoginViewModel2 @AssistedInject constructor(
SignMode2.Unknown -> error("Developer error, invalid sign mode")
SignMode2.SignIn -> handleSetUserNameForSignIn(action, null)
SignMode2.SignUp -> handleSetUserNameForSignUp(action)
- }.exhaustive
+ }
}
private fun handleSetUserPassword(action: LoginAction2.SetUserPassword) = withState { state ->
@@ -508,7 +507,7 @@ class LoginViewModel2 @AssistedInject constructor(
SignMode2.Unknown -> error("Developer error, invalid sign mode")
SignMode2.SignIn -> handleSignInWithPassword(action)
SignMode2.SignUp -> handleRegisterWithPassword(action)
- }.exhaustive
+ }
}
private fun handleRegisterWithPassword(action: LoginAction2.SetUserPassword) = withState { state ->
@@ -588,7 +587,7 @@ class LoginViewModel2 @AssistedInject constructor(
else -> {
onWellKnownError()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt
index 63e0398fc1..61dcd48779 100644
--- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt
@@ -65,18 +65,17 @@ class MatrixToBottomSheet :
override fun invalidate() = withState(viewModel) { state ->
super.invalidate()
when (state.linkType) {
- is PermalinkData.RoomLink -> {
+ is PermalinkData.RoomLink -> {
views.matrixToCardContentLoading.isVisible = state.roomPeekResult is Incomplete
showFragment(MatrixToRoomSpaceFragment::class, Bundle())
}
- is PermalinkData.UserLink -> {
+ is PermalinkData.UserLink -> {
views.matrixToCardContentLoading.isVisible = state.matrixItem is Incomplete
showFragment(MatrixToUserFragment::class, Bundle())
}
- is PermalinkData.GroupLink -> {
- }
- is PermalinkData.FallbackLink -> {
- }
+ is PermalinkData.GroupLink -> Unit
+ is PermalinkData.FallbackLink -> Unit
+ is PermalinkData.RoomEmailInviteLink -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt
index e741f6fb39..04c2c8dd44 100644
--- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt
@@ -28,7 +28,6 @@ import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.createdirect.DirectRoomHelper
@@ -49,8 +48,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
private val session: Session,
private val stringProvider: StringProvider,
private val directRoomHelper: DirectRoomHelper,
- private val errorFormatter: ErrorFormatter) :
- VectorViewModel(initialState) {
+ private val errorFormatter: ErrorFormatter
+) : VectorViewModel(initialState) {
@AssistedFactory
interface Factory : MavericksAssistedViewModelFactory {
@@ -61,22 +60,23 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
init {
when (initialState.linkType) {
- is PermalinkData.RoomLink -> {
+ is PermalinkData.RoomLink -> {
setState {
copy(roomPeekResult = Loading())
}
}
- is PermalinkData.UserLink -> {
+ is PermalinkData.UserLink -> {
setState {
copy(matrixItem = Loading())
}
}
- is PermalinkData.GroupLink -> {
+ is PermalinkData.GroupLink -> {
// Not yet supported
}
- is PermalinkData.FallbackLink -> {
+ is PermalinkData.FallbackLink -> {
// Not yet supported
}
+ is PermalinkData.RoomEmailInviteLink -> Unit
}
viewModelScope.launch(Dispatchers.IO) {
resolveLink(initialState)
@@ -263,7 +263,7 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
is MatrixToAction.OpenRoom -> {
_viewEvents.post(MatrixToViewEvents.NavigateToRoom(action.roomId))
}
- }.exhaustive
+ }
}
private fun handleJoinSpace(joinSpace: MatrixToAction.JoinSpace) {
diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
index cc02687d93..4c3ce80339 100644
--- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
+++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
@@ -320,6 +320,7 @@ class DefaultNavigator @Inject constructor(
}
}
}
+ null -> Unit
}
}
@@ -376,6 +377,7 @@ class DefaultNavigator @Inject constructor(
context.startActivity(intent)
}
}
+ null -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt
index 4078bb0b5c..e0e21a39a7 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt
@@ -47,11 +47,9 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
)
// Remove summary first to avoid briefly displaying it after dismissing the last notification
- when (summaryNotification) {
- SummaryNotification.Removed -> {
- Timber.d("Removing summary notification")
- notificationDisplayer.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID)
- }
+ if (summaryNotification == SummaryNotification.Removed) {
+ Timber.d("Removing summary notification")
+ notificationDisplayer.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID)
}
roomNotifications.forEach { wrapper ->
@@ -94,11 +92,9 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
}
// Update summary last to avoid briefly displaying it before other notifications
- when (summaryNotification) {
- is SummaryNotification.Update -> {
- Timber.d("Updating summary notification")
- notificationDisplayer.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, summaryNotification.notification)
- }
+ if (summaryNotification is SummaryNotification.Update) {
+ Timber.d("Updating summary notification")
+ notificationDisplayer.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, summaryNotification.notification)
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt b/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt
index 107c08da5a..163af5d8d1 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt
@@ -30,7 +30,6 @@ import im.vector.app.R
import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.resetBackstack
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityLoginBinding
@@ -257,7 +256,7 @@ class Login2Variant(
is LoginViewEvents2.OnSessionCreated -> handleOnSessionCreated(event)
is LoginViewEvents2.Finish -> terminate(true)
is LoginViewEvents2.CancelRegistration -> handleCancelRegistration()
- }.exhaustive
+ }
}
private fun handleCancelRegistration() {
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
index 6659058b4e..a18b9e62e0 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
@@ -18,11 +18,7 @@ package im.vector.app.features.onboarding
import android.content.Context
import android.net.Uri
-import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModelFactory
-import com.airbnb.mvrx.Success
-import com.airbnb.mvrx.Uninitialized
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -31,7 +27,6 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.configureAndStart
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.vectorStore
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -166,7 +161,7 @@ class OnboardingViewModel @AssistedInject constructor(
OnboardingAction.SaveSelectedProfilePicture -> updateProfilePicture()
is OnboardingAction.PostViewEvent -> _viewEvents.post(action.viewEvent)
OnboardingAction.StopEmailValidationCheck -> cancelWaitForEmailValidation()
- }.exhaustive
+ }
}
private fun handleSplashAction(resetConfig: Boolean, onboardingFlow: OnboardingFlow) {
@@ -222,6 +217,7 @@ class OnboardingViewModel @AssistedInject constructor(
.withAllowedFingerPrints(listOf(action.fingerprint))
.build()
)
+ else -> Unit
}
}
@@ -239,31 +235,19 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
- setState {
- copy(
- asyncLoginAction = Fail(Throwable("Bad configuration"))
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
- setState {
- copy(
- asyncLoginAction = Loading()
- )
- }
+ setState { copy(isLoading = true) }
currentJob = viewModelScope.launch {
try {
- safeLoginWizard.loginWithToken(action.loginToken)
+ val result = safeLoginWizard.loginWithToken(action.loginToken)
+ onSessionCreated(result, isAccountCreated = false)
} catch (failure: Throwable) {
+ setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(failure))
- setState {
- copy(
- asyncLoginAction = Fail(failure)
- )
- }
- null
}
- ?.let { onSessionCreated(it, isAccountCreated = false) }
}
}
}
@@ -271,7 +255,7 @@ class OnboardingViewModel @AssistedInject constructor(
private fun handleRegisterAction(action: RegisterAction) {
currentJob = viewModelScope.launch {
if (action.hasLoadingState()) {
- setState { copy(asyncRegistration = Loading()) }
+ setState { copy(isLoading = true) }
}
runCatching { registrationActionHandler.handleRegisterAction(registrationWizard, action) }
.fold(
@@ -292,7 +276,7 @@ class OnboardingViewModel @AssistedInject constructor(
}
}
)
- setState { copy(asyncRegistration = Uninitialized) }
+ setState { copy(isLoading = false) }
}
}
@@ -322,7 +306,7 @@ class OnboardingViewModel @AssistedInject constructor(
authenticationService.reset()
setState {
copy(
- asyncHomeServerLoginFlowRequest = Uninitialized,
+ isLoading = false,
homeServerUrlFromUser = null,
homeServerUrl = null,
loginMode = LoginMode.Unknown,
@@ -335,7 +319,7 @@ class OnboardingViewModel @AssistedInject constructor(
OnboardingAction.ResetSignMode -> {
setState {
copy(
- asyncHomeServerLoginFlowRequest = Uninitialized,
+ isLoading = false,
signMode = SignMode.Unknown,
loginMode = LoginMode.Unknown,
loginModeSupportedTypes = emptyList()
@@ -345,19 +329,13 @@ class OnboardingViewModel @AssistedInject constructor(
OnboardingAction.ResetLogin -> {
viewModelScope.launch {
authenticationService.cancelPendingLoginOrRegistration()
- setState {
- copy(
- asyncLoginAction = Uninitialized,
- asyncRegistration = Uninitialized
- )
- }
+ setState { copy(isLoading = false) }
}
}
OnboardingAction.ResetResetPassword -> {
setState {
copy(
- asyncResetPassword = Uninitialized,
- asyncResetMailConfirmed = Uninitialized,
+ isLoading = false,
resetPasswordEmail = null
)
}
@@ -403,7 +381,7 @@ class OnboardingViewModel @AssistedInject constructor(
handle(OnboardingAction.UpdateHomeServer(matrixOrgUrl))
ServerType.EMS,
ServerType.Other -> _viewEvents.post(OnboardingViewEvents.OnServerSelectionDone(action.serverType))
- }.exhaustive
+ }
}
private fun handleInitWith(action: OnboardingAction.InitWith) {
@@ -426,35 +404,23 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
- setState {
- copy(
- asyncResetPassword = Fail(Throwable("Bad configuration")),
- asyncResetMailConfirmed = Uninitialized
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
- setState {
- copy(
- asyncResetPassword = Loading(),
- asyncResetMailConfirmed = Uninitialized
- )
- }
+ setState { copy(isLoading = true) }
currentJob = viewModelScope.launch {
try {
safeLoginWizard.resetPassword(action.email, action.newPassword)
} catch (failure: Throwable) {
- setState {
- copy(
- asyncResetPassword = Fail(failure)
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(failure))
return@launch
}
setState {
copy(
- asyncResetPassword = Success(Unit),
+ isLoading = false,
resetPasswordEmail = action.email
)
}
@@ -468,34 +434,22 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
- setState {
- copy(
- asyncResetPassword = Uninitialized,
- asyncResetMailConfirmed = Fail(Throwable("Bad configuration"))
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
- setState {
- copy(
- asyncResetPassword = Uninitialized,
- asyncResetMailConfirmed = Loading()
- )
- }
+ setState { copy(isLoading = false) }
currentJob = viewModelScope.launch {
try {
safeLoginWizard.resetPasswordMailConfirmed()
} catch (failure: Throwable) {
- setState {
- copy(
- asyncResetMailConfirmed = Fail(failure)
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(failure))
return@launch
}
setState {
copy(
- asyncResetMailConfirmed = Success(Unit),
+ isLoading = false,
resetPasswordEmail = null
)
}
@@ -511,15 +465,11 @@ class OnboardingViewModel @AssistedInject constructor(
SignMode.SignIn -> handleLogin(action)
SignMode.SignUp -> handleRegisterWith(action)
SignMode.SignInWithMatrixId -> handleDirectLogin(action, null)
- }.exhaustive
+ }
}
private fun handleDirectLogin(action: OnboardingAction.LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?) {
- setState {
- copy(
- asyncLoginAction = Loading()
- )
- }
+ setState { copy(isLoading = true) }
currentJob = viewModelScope.launch {
val data = try {
@@ -541,16 +491,12 @@ class OnboardingViewModel @AssistedInject constructor(
else -> {
onWellKnownError()
}
- }.exhaustive
+ }
}
}
private fun onWellKnownError() {
- setState {
- copy(
- asyncLoginAction = Uninitialized
- )
- }
+ setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error))))
}
@@ -585,20 +531,12 @@ class OnboardingViewModel @AssistedInject constructor(
when (failure) {
is MatrixIdFailure.InvalidMatrixId,
is Failure.UnrecognizedCertificateFailure -> {
+ setState { copy(isLoading = false) }
// Display this error in a dialog
_viewEvents.post(OnboardingViewEvents.Failure(failure))
- setState {
- copy(
- asyncLoginAction = Uninitialized
- )
- }
}
else -> {
- setState {
- copy(
- asyncLoginAction = Fail(failure)
- )
- }
+ setState { copy(isLoading = false) }
}
}
}
@@ -607,37 +545,23 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
- setState {
- copy(
- asyncLoginAction = Fail(Throwable("Bad configuration"))
- )
- }
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
- setState {
- copy(
- asyncLoginAction = Loading()
- )
- }
-
+ setState { copy(isLoading = true) }
currentJob = viewModelScope.launch {
try {
- safeLoginWizard.login(
+ val result = safeLoginWizard.login(
action.username,
action.password,
action.initialDeviceName
)
+ reAuthHelper.data = action.password
+ onSessionCreated(result, isAccountCreated = false)
} catch (failure: Throwable) {
- setState {
- copy(
- asyncLoginAction = Fail(failure)
- )
- }
- null
+ setState { copy(isLoading = false) }
+ _viewEvents.post(OnboardingViewEvents.Failure(failure))
}
- ?.let {
- reAuthHelper.data = action.password
- onSessionCreated(it, isAccountCreated = false)
- }
}
}
}
@@ -678,12 +602,12 @@ class OnboardingViewModel @AssistedInject constructor(
true -> {
val personalizationState = createPersonalizationState(session, state)
setState {
- copy(asyncLoginAction = Success(Unit), personalizationState = personalizationState)
+ copy(isLoading = false, personalizationState = personalizationState)
}
_viewEvents.post(OnboardingViewEvents.OnAccountCreated)
}
false -> {
- setState { copy(asyncLoginAction = Success(Unit)) }
+ setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.OnAccountSignedIn)
}
}
@@ -712,14 +636,11 @@ class OnboardingViewModel @AssistedInject constructor(
} else {
currentJob = viewModelScope.launch {
try {
- authenticationService.createSessionFromSso(homeServerConnectionConfigFinal, action.credentials)
+ val result = authenticationService.createSessionFromSso(homeServerConnectionConfigFinal, action.credentials)
+ onSessionCreated(result, isAccountCreated = false)
} catch (failure: Throwable) {
- setState {
- copy(asyncLoginAction = Fail(failure))
- }
- null
+ setState { copy(isLoading = false) }
}
- ?.let { onSessionCreated(it, isAccountCreated = false) }
}
}
}
@@ -743,7 +664,7 @@ class OnboardingViewModel @AssistedInject constructor(
setState {
copy(
- asyncHomeServerLoginFlowRequest = Loading(),
+ isLoading = true,
// If user has entered https://matrix.org, ensure that server type is ServerType.MatrixOrg
// It is also useful to set the value again in the case of a certificate error on matrix.org
serverType = if (homeServerConnectionConfig.homeServerUri.toString() == matrixOrgUrl) {
@@ -757,14 +678,14 @@ class OnboardingViewModel @AssistedInject constructor(
val data = try {
authenticationService.getLoginFlow(homeServerConnectionConfig)
} catch (failure: Throwable) {
- _viewEvents.post(OnboardingViewEvents.Failure(failure))
setState {
copy(
- asyncHomeServerLoginFlowRequest = Uninitialized,
+ isLoading = false,
// If we were trying to retrieve matrix.org login flow, also reset the serverType
serverType = if (serverType == ServerType.MatrixOrg) ServerType.Unknown else serverType
)
}
+ _viewEvents.post(OnboardingViewEvents.Failure(failure))
null
}
@@ -785,7 +706,7 @@ class OnboardingViewModel @AssistedInject constructor(
setState {
copy(
- asyncHomeServerLoginFlowRequest = Uninitialized,
+ isLoading = false,
homeServerUrlFromUser = homeServerConnectionConfig.homeServerUri.toString(),
homeServerUrl = data.homeServerUrl,
loginMode = loginMode,
@@ -828,20 +749,20 @@ class OnboardingViewModel @AssistedInject constructor(
}
private fun updateDisplayName(displayName: String) {
- setState { copy(asyncDisplayName = Loading()) }
+ setState { copy(isLoading = true) }
viewModelScope.launch {
val activeSession = activeSessionHolder.getActiveSession()
try {
activeSession.setDisplayName(activeSession.myUserId, displayName)
setState {
copy(
- asyncDisplayName = Success(Unit),
+ isLoading = false,
personalizationState = personalizationState.copy(displayName = displayName)
)
}
handleDisplayNameStepComplete()
} catch (error: Throwable) {
- setState { copy(asyncDisplayName = Fail(error)) }
+ setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(error))
}
}
@@ -883,7 +804,7 @@ class OnboardingViewModel @AssistedInject constructor(
when (val pictureUri = state.personalizationState.selectedPictureUri) {
null -> _viewEvents.post(OnboardingViewEvents.Failure(NullPointerException("picture uri is missing from state")))
else -> {
- setState { copy(asyncProfilePicture = Loading()) }
+ setState { copy(isLoading = true) }
viewModelScope.launch {
val activeSession = activeSessionHolder.getActiveSession()
try {
@@ -894,12 +815,12 @@ class OnboardingViewModel @AssistedInject constructor(
)
setState {
copy(
- asyncProfilePicture = Success(Unit),
+ isLoading = false,
)
}
onProfilePictureSaved()
} catch (error: Throwable) {
- setState { copy(asyncProfilePicture = Fail(error)) }
+ setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(error))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
index 8747de6da8..b98e811679 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
@@ -18,24 +18,15 @@ package im.vector.app.features.onboarding
import android.net.Uri
import android.os.Parcelable
-import com.airbnb.mvrx.Async
-import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.PersistState
-import com.airbnb.mvrx.Uninitialized
import im.vector.app.features.login.LoginMode
import im.vector.app.features.login.ServerType
import im.vector.app.features.login.SignMode
import kotlinx.parcelize.Parcelize
data class OnboardingViewState(
- val asyncLoginAction: Async = Uninitialized,
- val asyncHomeServerLoginFlowRequest: Async = Uninitialized,
- val asyncResetPassword: Async = Uninitialized,
- val asyncResetMailConfirmed: Async = Uninitialized,
- val asyncRegistration: Async = Uninitialized,
- val asyncDisplayName: Async = Uninitialized,
- val asyncProfilePicture: Async = Uninitialized,
+ val isLoading: Boolean = false,
@PersistState
val onboardingFlow: OnboardingFlow? = null,
@@ -71,18 +62,7 @@ data class OnboardingViewState(
@PersistState
val personalizationState: PersonalizationState = PersonalizationState()
-) : MavericksState {
-
- fun isLoading(): Boolean {
- return asyncLoginAction is Loading ||
- asyncHomeServerLoginFlowRequest is Loading ||
- asyncResetPassword is Loading ||
- asyncResetMailConfirmed is Loading ||
- asyncRegistration is Loading ||
- asyncDisplayName is Loading ||
- asyncProfilePicture is Loading
- }
-}
+) : MavericksState
enum class OnboardingFlow {
SignIn,
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractFtueAuthFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractFtueAuthFragment.kt
index 0caf2ea152..64e29766c5 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractFtueAuthFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractFtueAuthFragment.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.features.onboarding.OnboardingAction
@@ -35,8 +34,6 @@ import im.vector.app.features.onboarding.OnboardingViewModel
import im.vector.app.features.onboarding.OnboardingViewState
import kotlinx.coroutines.CancellationException
import org.matrix.android.sdk.api.failure.Failure
-import org.matrix.android.sdk.api.failure.MatrixError
-import javax.net.ssl.HttpsURLConnection
/**
* Parent Fragment for all the login/registration screens
@@ -73,7 +70,7 @@ abstract class AbstractFtueAuthFragment : VectorBaseFragment
// This is handled by the Activity
Unit
- }.exhaustive
+ }
}
override fun showFailure(throwable: Throwable) {
@@ -86,21 +83,8 @@ abstract class AbstractFtueAuthFragment : VectorBaseFragment
/* Ignore this error, user has cancelled the action */
Unit
- is Failure.ServerError ->
- if (throwable.error.code == MatrixError.M_FORBIDDEN &&
- throwable.httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */) {
- MaterialAlertDialogBuilder(requireActivity())
- .setTitle(R.string.dialog_title_error)
- .setMessage(getString(R.string.login_registration_disabled))
- .setPositiveButton(R.string.ok, null)
- .show()
- } else {
- onError(throwable)
- }
- is Failure.UnrecognizedCertificateFailure ->
- showUnrecognizedCertificateFailure(throwable)
- else ->
- onError(throwable)
+ is Failure.UnrecognizedCertificateFailure -> showUnrecognizedCertificateFailure(throwable)
+ else -> onError(throwable)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt
index 5f15d9a35d..53c9fd4fcc 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt
@@ -26,11 +26,8 @@ import androidx.autofill.HintConstants
import androidx.core.text.isDigitsOnly
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
-import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Loading
-import com.airbnb.mvrx.Success
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.hidePassword
import im.vector.app.core.extensions.toReducedUrl
@@ -47,9 +44,12 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
-import org.matrix.android.sdk.api.failure.Failure
-import org.matrix.android.sdk.api.failure.MatrixError
import org.matrix.android.sdk.api.failure.isInvalidPassword
+import org.matrix.android.sdk.api.failure.isInvalidUsername
+import org.matrix.android.sdk.api.failure.isLoginEmailUnknown
+import org.matrix.android.sdk.api.failure.isRegistrationDisabled
+import org.matrix.android.sdk.api.failure.isUsernameInUse
+import org.matrix.android.sdk.api.failure.isWeakPassword
import reactivecircus.flowbinding.android.widget.textChanges
import javax.inject.Inject
@@ -105,7 +105,7 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<
views.loginField.setAutofillHints(HintConstants.AUTOFILL_HINT_USERNAME)
views.passwordField.setAutofillHints(HintConstants.AUTOFILL_HINT_PASSWORD)
}
- }.exhaustive
+ }
}
}
@@ -115,7 +115,7 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<
SignMode.SignUp -> SocialLoginButtonsView.Mode.MODE_SIGN_UP
SignMode.SignIn,
SignMode.SignInWithMatrixId -> SocialLoginButtonsView.Mode.MODE_SIGN_IN
- }.exhaustive
+ }
}
private fun submit() {
@@ -258,12 +258,31 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<
}
override fun onError(throwable: Throwable) {
- // Show M_WEAK_PASSWORD error in the password field
- if (throwable is Failure.ServerError &&
- throwable.error.code == MatrixError.M_WEAK_PASSWORD) {
- views.passwordFieldTil.error = errorFormatter.toHumanReadable(throwable)
- } else {
- views.loginFieldTil.error = errorFormatter.toHumanReadable(throwable)
+ // Trick to display the error without text.
+ views.loginFieldTil.error = " "
+ when {
+ throwable.isUsernameInUse() || throwable.isInvalidUsername() -> {
+ views.loginFieldTil.error = errorFormatter.toHumanReadable(throwable)
+ }
+ throwable.isLoginEmailUnknown() -> {
+ views.loginFieldTil.error = getString(R.string.login_login_with_email_error)
+ }
+ throwable.isInvalidPassword() && spaceInPassword() -> {
+ views.passwordFieldTil.error = getString(R.string.auth_invalid_login_param_space_in_password)
+ }
+ throwable.isWeakPassword() || throwable.isInvalidPassword() -> {
+ views.passwordFieldTil.error = errorFormatter.toHumanReadable(throwable)
+ }
+ throwable.isRegistrationDisabled() -> {
+ MaterialAlertDialogBuilder(requireActivity())
+ .setTitle(R.string.dialog_title_error)
+ .setMessage(getString(R.string.login_registration_disabled))
+ .setPositiveButton(R.string.ok, null)
+ .show()
+ }
+ else -> {
+ super.onError(throwable)
+ }
}
}
@@ -276,39 +295,9 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<
setupSocialLoginButtons(state)
setupButtons(state)
- when (state.asyncLoginAction) {
- is Loading -> {
- // Ensure password is hidden
- views.passwordField.hidePassword()
- }
- is Fail -> {
- val error = state.asyncLoginAction.error
- if (error is Failure.ServerError &&
- error.error.code == MatrixError.M_FORBIDDEN &&
- error.error.message.isEmpty()) {
- // Login with email, but email unknown
- views.loginFieldTil.error = getString(R.string.login_login_with_email_error)
- } else {
- // Trick to display the error without text.
- views.loginFieldTil.error = " "
- if (error.isInvalidPassword() && spaceInPassword()) {
- views.passwordFieldTil.error = getString(R.string.auth_invalid_login_param_space_in_password)
- } else {
- views.passwordFieldTil.error = errorFormatter.toHumanReadable(error)
- }
- }
- }
- // Success is handled by the LoginActivity
- is Success -> Unit
- }
-
- when (state.asyncRegistration) {
- is Loading -> {
- // Ensure password is hidden
- views.passwordField.hidePassword()
- }
- // Success is handled by the LoginActivity
- is Success -> Unit
+ if (state.isLoading) {
+ // Ensure password is hidden
+ views.passwordField.hidePassword()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt
index 6a224dfae8..b612ec34b5 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt
@@ -21,9 +21,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
-import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Loading
-import com.airbnb.mvrx.Success
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.hideKeyboard
@@ -54,10 +51,13 @@ class FtueAuthResetPasswordFragment @Inject constructor() : AbstractFtueAuthFrag
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
-
setupSubmitButton()
}
+ override fun onError(throwable: Throwable) {
+ views.resetPasswordEmailTil.error = errorFormatter.toHumanReadable(throwable)
+ }
+
private fun setupUi(state: OnboardingViewState) {
views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.homeServerUrlFromUser.toReducedUrl())
}
@@ -116,16 +116,9 @@ class FtueAuthResetPasswordFragment @Inject constructor() : AbstractFtueAuthFrag
override fun updateWithState(state: OnboardingViewState) {
setupUi(state)
-
- when (state.asyncResetPassword) {
- is Loading -> {
- // Ensure new password is hidden
- views.passwordField.hidePassword()
- }
- is Fail -> {
- views.resetPasswordEmailTil.error = errorFormatter.toHumanReadable(state.asyncResetPassword.error)
- }
- is Success -> Unit
+ if (state.isLoading) {
+ // Ensure new password is hidden
+ views.passwordField.hidePassword()
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordMailConfirmationFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordMailConfirmationFragment.kt
index 1d5e1aa00a..f6141a4900 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordMailConfirmationFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordMailConfirmationFragment.kt
@@ -20,8 +20,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Success
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.databinding.FragmentLoginResetPasswordMailConfirmationBinding
@@ -59,23 +57,20 @@ class FtueAuthResetPasswordMailConfirmationFragment @Inject constructor() : Abst
override fun updateWithState(state: OnboardingViewState) {
setupUi(state)
+ }
- when (state.asyncResetMailConfirmed) {
- is Fail -> {
- // Link in email not yet clicked ?
- val message = if (state.asyncResetMailConfirmed.error.is401()) {
- getString(R.string.auth_reset_password_error_unauthorized)
- } else {
- errorFormatter.toHumanReadable(state.asyncResetMailConfirmed.error)
- }
-
- MaterialAlertDialogBuilder(requireActivity())
- .setTitle(R.string.dialog_title_error)
- .setMessage(message)
- .setPositiveButton(R.string.ok, null)
- .show()
- }
- is Success -> Unit
+ override fun onError(throwable: Throwable) {
+ // Link in email not yet clicked ?
+ val message = if (throwable.is401()) {
+ getString(R.string.auth_reset_password_error_unauthorized)
+ } else {
+ errorFormatter.toHumanReadable(throwable)
}
+
+ MaterialAlertDialogBuilder(requireActivity())
+ .setTitle(R.string.dialog_title_error)
+ .setMessage(message)
+ .setPositiveButton(R.string.ok, null)
+ .show()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt
index 79a974038b..2b3a43df5d 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt
@@ -31,7 +31,6 @@ import im.vector.app.R
import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.popBackstack
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.ScreenOrientationLocker
@@ -122,7 +121,7 @@ class FtueAuthVariant(
private fun updateWithState(viewState: OnboardingViewState) {
isForceLoginFallbackEnabled = viewState.isForceLoginFallbackEnabled
- views.loginLoading.isVisible = viewState.isLoading()
+ views.loginLoading.isVisible = viewState.isLoading
}
override fun setIsLoading(isLoading: Boolean) = Unit
@@ -229,7 +228,7 @@ class FtueAuthVariant(
OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture()
OnboardingViewEvents.OnPersonalizationComplete -> onPersonalizationComplete()
OnboardingViewEvents.OnBack -> activity.popBackstack()
- }.exhaustive
+ }
}
private fun registrationShouldFallback(registrationFlowResult: OnboardingViewEvents.RegistrationFlowResult) =
@@ -281,7 +280,7 @@ class FtueAuthVariant(
SignMode.SignUp -> Unit // This case is processed in handleOnboardingViewEvents
SignMode.SignIn -> handleSignInSelected(state)
SignMode.SignInWithMatrixId -> handleSignInWithMatrixId(state)
- }.exhaustive
+ }
}
private fun handleSignInSelected(state: OnboardingViewState) {
diff --git a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollFragment.kt b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollFragment.kt
index 4483b00158..2abff7f22b 100644
--- a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollFragment.kt
@@ -27,7 +27,6 @@ import com.airbnb.mvrx.args
import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentCreatePollBinding
import im.vector.app.features.poll.create.CreatePollViewModel.Companion.MAX_OPTIONS_COUNT
@@ -68,7 +67,7 @@ class CreatePollFragment @Inject constructor(
views.createPollToolbar.title = getString(R.string.edit_poll_title)
views.createPollButton.text = getString(R.string.edit_poll_title)
}
- }.exhaustive
+ }
views.createPollRecyclerView.configureWith(controller, disableItemAnimation = true)
// workaround for https://github.com/vector-im/element-android/issues/4735
diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
index dda7b2e2eb..b23f2f171d 100644
--- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt
@@ -24,7 +24,6 @@ import androidx.activity.result.ActivityResultLauncher
import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
@@ -51,7 +50,7 @@ class QrCodeScannerActivity() : VectorBaseActivity() {
finish()
}
else -> Unit
- }.exhaustive
+ }
}
if (isFirstCreation()) {
diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt
index a77bd32f26..0cb49746f1 100644
--- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import kotlinx.coroutines.Dispatchers
@@ -127,6 +126,6 @@ class RequireActiveMembershipViewModel @AssistedInject constructor(
}
roomIdFlow.tryEmit(Optional.from(action.roomId))
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt
index 14b50c2745..b8bba347fd 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt
@@ -28,7 +28,6 @@ import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.trackItemsVisibilityChange
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.showOptimizedSnackbar
@@ -96,7 +95,7 @@ class PublicRoomsFragment @Inject constructor(
is RoomDirectoryViewEvents.Failure -> {
views.coordinatorLayout.showOptimizedSnackbar(errorFormatter.toHumanReadable(viewEvents.throwable))
}
- }.exhaustive
+ }
}
override fun onDestroyView() {
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
index 48da9f4fa0..f0df31342e 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt
@@ -62,8 +62,8 @@ class RoomDirectoryActivity : VectorBaseActivity(), Matri
.stream()
.onEach { sharedAction ->
when (sharedAction) {
- is RoomDirectorySharedAction.Back -> popBackstack()
- is RoomDirectorySharedAction.CreateRoom -> {
+ is RoomDirectorySharedAction.Back -> popBackstack()
+ is RoomDirectorySharedAction.CreateRoom -> {
// Transmit the filter to the CreateRoomFragment
withState(roomDirectoryViewModel) {
addFragmentToBackstack(
@@ -73,9 +73,10 @@ class RoomDirectoryActivity : VectorBaseActivity(), Matri
)
}
}
- is RoomDirectorySharedAction.ChangeProtocol ->
+ is RoomDirectorySharedAction.ChangeProtocol ->
addFragmentToBackstack(views.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java)
- is RoomDirectorySharedAction.Close -> finish()
+ is RoomDirectorySharedAction.Close -> finish()
+ is RoomDirectorySharedAction.CreateRoomSuccess -> Unit
}
}
.launchIn(lifecycleScope)
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt
index 2bd41ae3af..2871513c1f 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt
@@ -34,7 +34,6 @@ import im.vector.app.R
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider
@@ -94,7 +93,7 @@ class CreateRoomFragment @Inject constructor(
when (it) {
CreateRoomViewEvents.Quit -> vectorBaseActivity.onBackPressed()
is CreateRoomViewEvents.Failure -> showFailure(it.throwable)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
index 3b2e9de2d1..7d65c44a57 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt
@@ -28,7 +28,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.AppStateHandler
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.plan.CreatedRoom
@@ -138,7 +137,7 @@ class CreateRoomViewModel @AssistedInject constructor(
CreateRoomAction.Reset -> doReset()
CreateRoomAction.ToggleShowAdvanced -> toggleShowAdvanced()
is CreateRoomAction.DisableFederation -> disableFederation(action)
- }.exhaustive
+ }
}
private fun disableFederation(action: CreateRoomAction.DisableFederation) {
@@ -281,7 +280,7 @@ class CreateRoomViewModel @AssistedInject constructor(
// Preset
preset = CreateRoomPreset.PRESET_PRIVATE_CHAT
}
- }.exhaustive
+ }
// Disabling federation
disableFederation = state.disableFederation
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
index 08e044630d..7d121d1ff4 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
@@ -22,7 +22,6 @@ import android.view.inputmethod.EditorInfo
import android.widget.TextView
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
@@ -60,7 +59,7 @@ class RoomDirectoryPickerController @Inject constructor(
val host = this
when (val asyncThirdPartyProtocol = data.asyncThirdPartyRequest) {
- is Success -> {
+ is Success -> {
data.directories.join(
each = { _, roomDirectoryServer -> buildDirectory(roomDirectoryServer) },
between = { idx, _ -> buildDivider(idx) }
@@ -71,12 +70,13 @@ class RoomDirectoryPickerController @Inject constructor(
heightInPx(host.dimensionConverter.dpToPx(16))
}
}
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("loading")
}
}
- is Fail -> {
+ is Fail -> {
errorWithRetryItem {
id("error")
text(host.errorFormatter.toHumanReadable(asyncThirdPartyProtocol.error))
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt
index a5673e78a2..51af9a8286 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt
@@ -27,7 +27,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -104,7 +103,7 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor(
is RoomDirectoryPickerAction.SetServerUrl -> handleSetServerUrl(action)
RoomDirectoryPickerAction.Submit -> handleSubmit()
is RoomDirectoryPickerAction.RemoveServer -> handleRemoveServer(action)
- }.exhaustive
+ }
}
private fun handleEnterEditMode() {
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
index 42bec8c8b3..a22dc7ed95 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt
@@ -24,7 +24,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.AnalyticsTracker
@@ -204,7 +203,7 @@ class RoomPreviewViewModel @AssistedInject constructor(
when (action) {
is RoomPreviewAction.Join -> handleJoinRoom()
RoomPreviewAction.JoinThirdParty -> handleJoinRoomThirdParty()
- }.exhaustive
+ }
}
private fun handleJoinRoomThirdParty() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
index 7e919fb663..d9ed6d227a 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt
@@ -25,8 +25,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
@@ -38,7 +39,6 @@ import im.vector.app.core.dialogs.ConfirmationDialogBuilder
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.copyOnLongClick
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.StateView
import im.vector.app.core.platform.VectorBaseFragment
@@ -133,7 +133,7 @@ class RoomMemberProfileFragment @Inject constructor(
is RoomMemberProfileViewEvents.OnBanActionSuccess -> Unit
is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> Unit
is RoomMemberProfileViewEvents.OnInviteActionSuccess -> Unit
- }.exhaustive
+ }
}
setupLongClicks()
}
@@ -198,18 +198,19 @@ class RoomMemberProfileFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state ->
when (val asyncUserMatrixItem = state.userMatrixItem) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
views.matrixProfileToolbarTitleView.text = state.userId
avatarRenderer.render(MatrixItem.UserItem(state.userId, null, null), views.matrixProfileToolbarAvatarImageView)
headerViews.memberProfileStateView.state = StateView.State.Loading
}
- is Fail -> {
+ is Fail -> {
avatarRenderer.render(MatrixItem.UserItem(state.userId, null, null), views.matrixProfileToolbarAvatarImageView)
views.matrixProfileToolbarTitleView.text = state.userId
val failureMessage = errorFormatter.toHumanReadable(asyncUserMatrixItem.error)
headerViews.memberProfileStateView.state = StateView.State.Error(failureMessage)
}
- is Success -> {
+ is Success -> {
val userMatrixItem = asyncUserMatrixItem()
headerViews.memberProfileStateView.state = StateView.State.Content
headerViews.memberProfileIdView.text = userMatrixItem.id
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
index a79a9f4c1d..db54f27910 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt
@@ -28,7 +28,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -170,7 +169,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
RoomMemberProfileAction.InviteUser -> handleInviteAction()
is RoomMemberProfileAction.SetUserColorOverride -> handleSetUserColorOverride(action)
is RoomMemberProfileAction.OpenOrCreateDm -> handleOpenOrCreateDm(action)
- }.exhaustive
+ }
}
private fun handleOpenOrCreateDm(action: RoomMemberProfileAction.OpenOrCreateDm) {
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
index bb2317b59c..8df0b3ffd5 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
@@ -29,7 +29,6 @@ import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.commitTransaction
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetWithFragmentsBinding
import im.vector.app.features.crypto.verification.VerificationBottomSheet
@@ -57,7 +56,7 @@ class DeviceListBottomSheet :
transactionId = it.txID
).show(requireActivity().supportFragmentManager, "REQPOP")
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
index d2491237ca..03e07a2f82 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
@@ -28,7 +28,6 @@ import dagger.hilt.EntryPoints
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.SingletonEntryPoint
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
@@ -94,7 +93,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
is DeviceListAction.SelectDevice -> selectDevice(action)
is DeviceListAction.DeselectDevice -> deselectDevice()
is DeviceListAction.ManuallyVerify -> manuallyVerify(action)
- }.exhaustive
+ }
}
private fun refreshSelectedId() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
index 4c6d2ed2e3..12a5d94eca 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore
@@ -102,7 +101,7 @@ class RoomProfileActivity :
RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings()
- }.exhaustive
+ }
}
.launchIn(lifecycleScope)
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
index b13ef2a5d1..ba9280dc59 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
@@ -37,7 +37,6 @@ import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.copyOnLongClick
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.copyToClipboard
@@ -127,7 +126,7 @@ class RoomProfileFragment @Inject constructor(
is RoomProfileViewEvents.ShareRoomProfile -> onShareRoomProfile(it.permalink)
is RoomProfileViewEvents.OnShortcutReady -> addShortcut(it)
RoomProfileViewEvents.DismissLoading -> dismissLoadingDialog()
- }.exhaustive
+ }
}
roomListQuickActionsSharedActionViewModel
.stream()
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
index b7c7d24888..61013c8eb6 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt
@@ -24,7 +24,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.ShortcutCreator
@@ -137,7 +136,7 @@ class RoomProfileViewModel @AssistedInject constructor(
is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile()
RoomProfileAction.CreateShortcut -> handleCreateShortcut()
RoomProfileAction.RestoreEncryptionState -> restoreEncryptionState()
- }.exhaustive
+ }
}
fun isPublicRoom(): Boolean {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
index 03e6ab9984..fcf6bc3a47 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
@@ -199,12 +199,13 @@ class RoomAliasController @Inject constructor(
}
when (val localAliases = data.localAliases) {
- is Uninitialized -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("loadingAliases")
}
}
- is Success -> {
+ is Success -> {
if (localAliases().isEmpty()) {
settingsInfoItem {
id("locEmpty")
@@ -220,7 +221,7 @@ class RoomAliasController @Inject constructor(
}
}
}
- is Fail -> {
+ is Fail -> {
errorWithRetryItem {
id("alt_error")
text(host.errorFormatter.toHumanReadable(localAliases.error))
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt
index e48ce54e6c..2a738fd07c 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt
@@ -29,7 +29,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.shareText
import im.vector.app.core.utils.toast
@@ -77,7 +76,7 @@ class RoomAliasFragment @Inject constructor(
when (it) {
is RoomAliasViewEvents.Failure -> showFailure(it.throwable)
RoomAliasViewEvents.Success -> showSuccess()
- }.exhaustive
+ }
}
sharedActionViewModel
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
index 19f600e5de..adffbcbd06 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt
@@ -26,7 +26,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import kotlinx.coroutines.flow.launchIn
@@ -190,7 +189,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
is RoomAliasAction.RemoveLocalAlias -> handleRemoveLocalAlias(action)
is RoomAliasAction.PublishAlias -> handlePublishAlias(action)
RoomAliasAction.Retry -> handleRetry()
- }.exhaustive
+ }
}
private fun handleRetry() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
index d7efc2fb79..ec249c75ba 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
@@ -84,7 +83,7 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia
is RoomBannedMemberListAction.QueryInfo -> onQueryBanInfo(action.roomMemberSummary)
is RoomBannedMemberListAction.UnBanUser -> unBanUser(action.roomMemberSummary)
is RoomBannedMemberListAction.Filter -> handleFilter(action)
- }.exhaustive
+ }
}
private fun handleFilter(action: RoomBannedMemberListAction.Filter) {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
index 0bbdd87f3e..c9a70fbef8 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
@@ -181,7 +180,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
when (action) {
is RoomMemberListAction.RevokeThreePidInvite -> handleRevokeThreePidInvite(action)
is RoomMemberListAction.FilterMemberList -> handleFilterMemberList(action)
- }.exhaustive
+ }
}
private fun handleRevokeThreePidInvite(action: RoomMemberListAction.RevokeThreePidInvite) {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
index 0d5ac7dea8..c1175796fb 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt
@@ -27,7 +27,6 @@ import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.toast
import im.vector.app.databinding.FragmentRoomSettingGenericBinding
@@ -67,7 +66,7 @@ class RoomPermissionsFragment @Inject constructor(
when (it) {
is RoomPermissionsViewEvents.Failure -> showFailure(it.throwable)
RoomPermissionsViewEvents.Success -> showSuccess()
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
index 7e8a66d12a..6fbc545b6c 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import kotlinx.coroutines.flow.launchIn
@@ -90,7 +89,7 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat
when (action) {
is RoomPermissionsAction.UpdatePermission -> updatePermission(action)
RoomPermissionsAction.ToggleShowAllPermissions -> toggleShowAllPermissions()
- }.exhaustive
+ }
}
private fun toggleShowAllPermissions() {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt
index 51f6b247d4..0bde35f41e 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt
@@ -33,7 +33,6 @@ import im.vector.app.R
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
@@ -98,7 +97,7 @@ class RoomSettingsFragment @Inject constructor(
ignoreChanges = true
vectorBaseActivity.onBackPressed()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
index a0325cfc2b..8ad5bcdce6 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.settings.VectorPreferences
@@ -201,7 +200,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
is RoomSettingsAction.SetRoomGuestAccess -> handleSetGuestAccess(action)
is RoomSettingsAction.Save -> saveSettings()
is RoomSettingsAction.Cancel -> cancel()
- }.exhaustive
+ }
}
private fun handleSetRoomJoinRule(action: RoomSettingsAction.SetRoomJoinRule) = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt
index 548ec9cfe4..f1897761b2 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt
@@ -29,7 +29,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.styleMatchingText
@@ -180,7 +179,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor(
is RoomJoinRuleChooseRestrictedActions.SelectJoinRules -> handleSelectRule(action)
is RoomJoinRuleChooseRestrictedActions.SwitchToRoomAfterMigration -> handleSwitchToRoom(action)
RoomJoinRuleChooseRestrictedActions.DoUpdateJoinRules -> handleSubmit()
- }.exhaustive
+ }
checkForChanges()
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt
index a0adf42d5b..6a115ad272 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt
@@ -28,7 +28,6 @@ import com.airbnb.mvrx.withState
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.intent.getMimeTypeFromUri
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.saveMedia
@@ -99,7 +98,7 @@ class RoomUploadsFragment @Inject constructor(
Unit
}
is RoomUploadsViewEvents.Failure -> showFailure(it.throwable)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt
index 92ff33395e..c9aaca4373 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
@@ -110,7 +109,7 @@ class RoomUploadsViewModel @AssistedInject constructor(
is RoomUploadsAction.Share -> handleShare(action)
RoomUploadsAction.Retry -> handleLoadMore()
RoomUploadsAction.LoadMore -> handleLoadMore()
- }.exhaustive
+ }
}
private fun handleShare(action: RoomUploadsAction.Share) {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt
index 1739378761..953838aecd 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt
@@ -24,6 +24,7 @@ import androidx.core.content.ContextCompat
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.parentFragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.app.R
@@ -91,6 +92,7 @@ class RoomUploadsFilesFragment @Inject constructor(
override fun invalidate() = withState(uploadsViewModel) { state ->
if (state.fileEvents.isEmpty()) {
when (state.asyncEventsRequest) {
+ Uninitialized,
is Loading -> {
views.genericStateViewListStateView.state = StateView.State.Loading
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt
index eb4337cffa..2f33f8403c 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt
@@ -29,6 +29,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.parentFragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.appbar.AppBarLayout
@@ -188,6 +189,7 @@ class RoomUploadsMediaFragment @Inject constructor(
override fun invalidate() = withState(uploadsViewModel) { state ->
if (state.mediaEvents.isEmpty()) {
when (state.asyncEventsRequest) {
+ Uninitialized,
is Loading -> {
views.genericStateViewListStateView.state = StateView.State.Loading
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
index 352c5768fb..8d93edc0ec 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
@@ -201,7 +201,13 @@ class VectorPreferences @Inject constructor(private val context: Context) {
private const val TAKE_PHOTO_VIDEO_MODE = "TAKE_PHOTO_VIDEO_MODE"
private const val SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE = "SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE"
- const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES"
+
+ // This key will be used to identify clients with the old thread support enabled io.element.thread
+ const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES"
+
+ // This key will be used to identify clients with the new thread support enabled m.thread
+ const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES_FINAL"
+ const val SETTINGS_THREAD_MESSAGES_SYNCED = "SETTINGS_THREAD_MESSAGES_SYNCED"
// Possible values for TAKE_PHOTO_VIDEO_MODE
const val TAKE_PHOTO_VIDEO_MODE_ALWAYS_ASK = 0
@@ -1006,7 +1012,56 @@ class VectorPreferences @Inject constructor(private val context: Context) {
return defaultPrefs.getBoolean(SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE, true)
}
+ /**
+ * Indicates whether or not thread messages are enabled
+ */
fun areThreadMessagesEnabled(): Boolean {
- return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, false)
+ return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, getDefault(R.bool.settings_labs_thread_messages_default))
+ }
+
+ /**
+ * Manually sets thread messages enabled, useful for migrating users from io.element.thread
+ */
+ fun setThreadMessagesEnabled() {
+ defaultPrefs
+ .edit()
+ .putBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES, true)
+ .apply()
+ }
+
+ /**
+ * Indicates whether or not the user will be notified about the new thread support
+ * We should notify the user only if he had old thread support enabled
+ */
+ fun shouldNotifyUserAboutThreads(): Boolean {
+ return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS, false)
+ }
+
+ /**
+ * Indicates that the user have been notified about threads migration
+ */
+ fun userNotifiedAboutThreads() {
+ defaultPrefs
+ .edit()
+ .putBoolean(SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS, false)
+ .apply()
+ }
+
+ /**
+ * Indicates whether or not we should clear cache for threads migration.
+ * Default value is true, for fresh installs and updates
+ */
+ fun shouldMigrateThreads(): Boolean {
+ return defaultPrefs.getBoolean(SETTINGS_THREAD_MESSAGES_SYNCED, true)
+ }
+
+ /**
+ * Indicates that there no longer threads migration needed
+ */
+ fun setShouldMigrateThreads(shouldMigrate: Boolean) {
+ defaultPrefs
+ .edit()
+ .putBoolean(SETTINGS_THREAD_MESSAGES_SYNCED, shouldMigrate)
+ .apply()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt
index 118e820f84..003832fb97 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt
@@ -42,6 +42,8 @@ class VectorSettingsLabsFragment @Inject constructor(
// clear cache
findPreference(VectorPreferences.SETTINGS_LABS_ENABLE_THREAD_MESSAGES)?.let {
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
+ // We should migrate threads only if threads are disabled
+ vectorPreferences.setShouldMigrateThreads(!vectorPreferences.areThreadMessagesEnabled())
lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled())
displayLoadingView()
MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true))
diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt
index 631c375e62..4397da00c4 100644
--- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt
@@ -25,7 +25,6 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.airbnb.mvrx.fragmentViewModel
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentDeactivateAccountBinding
@@ -128,7 +127,7 @@ class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment {
views.waitingView.waitingView.isVisible = false
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
index 644b7f33dd..5e691f64b2 100644
--- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.auth.ReAuthActivity
@@ -146,7 +145,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
uiaContinuation = null
pendingAuth = null
}
- }.exhaustive
+ }
}
private fun handleInitializeXSigningError(failure: Throwable) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt
index 5bbb03c8a4..407af19151 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt
@@ -32,7 +32,6 @@ import im.vector.app.R
import im.vector.app.core.dialogs.ManuallyVerifyDialog
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.DialogBaseEditTextBinding
@@ -90,7 +89,7 @@ class VectorSettingsDevicesFragment @Inject constructor(
viewModel.handle(DevicesAction.MarkAsManuallyVerified(it.cryptoDeviceInfo))
}
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
index f3ae18a72f..4748aeb45e 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
@@ -21,6 +21,7 @@ import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.core.epoxy.loadingItem
import im.vector.app.core.resources.StringProvider
@@ -45,6 +46,7 @@ class AccountDataEpoxyController @Inject constructor(
if (data == null) return
val host = this
when (data.accountData) {
+ Uninitialized,
is Loading -> {
loadingItem {
id("loading")
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt
index 6289699687..9576b84e98 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.launch
@@ -51,7 +50,7 @@ class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: A
override fun handle(action: AccountDataAction) {
when (action) {
is AccountDataAction.DeleteAccountData -> handleDeleteAccountData(action)
- }.exhaustive
+ }
}
private fun handleDeleteAccountData(action: AccountDataAction.DeleteAccountData) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt
index f480eb2db8..fd1cd3480d 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt
@@ -29,7 +29,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.platform.VectorViewModelAction
@@ -64,7 +63,7 @@ class KeyRequestViewModel @AssistedInject constructor(
override fun handle(action: KeyRequestAction) {
when (action) {
is KeyRequestAction.ExportAudit -> exportAudit(action)
- }.exhaustive
+ }
}
private fun exportAudit(action: KeyRequestAction.ExportAudit) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt
index d807fc620a..db2d07feef 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt
@@ -33,7 +33,6 @@ import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.tabs.TabLayoutMediator
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.selectTxtFileToWrite
@@ -111,7 +110,7 @@ class KeyRequestsFragment @Inject constructor() : VectorBaseFragment os.write(it.raw.toByteArray()) }
}
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt
index 509014492d..5c188fe933 100644
--- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt
@@ -30,7 +30,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentGenericRecyclerBinding
import javax.inject.Inject
@@ -57,7 +56,7 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor(
when (it) {
is IgnoredUsersViewEvents.Loading -> showLoading(it.message)
is IgnoredUsersViewEvents.Failure -> showFailure(it.throwable)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt
index 9d58535490..1497c793c2 100644
--- a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -50,7 +49,7 @@ class LegalsViewModel @AssistedInject constructor(
override fun handle(action: LegalsAction) {
when (action) {
LegalsAction.Refresh -> loadData()
- }.exhaustive
+ }
}
private fun loadData() = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
index 4e1c62a4ec..cffef0da7b 100644
--- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
@@ -17,12 +17,16 @@
package im.vector.app.features.settings.locale
import com.airbnb.epoxy.TypedEpoxyController
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Fail
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
+import im.vector.app.core.epoxy.errorWithRetryItem
import im.vector.app.core.epoxy.loadingItem
import im.vector.app.core.epoxy.noResultItem
import im.vector.app.core.epoxy.profiles.profileSectionItem
+import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.safeCapitalize
import im.vector.app.features.settings.VectorLocale
@@ -32,7 +36,8 @@ import javax.inject.Inject
class LocalePickerController @Inject constructor(
private val vectorPreferences: VectorPreferences,
- private val stringProvider: StringProvider
+ private val stringProvider: StringProvider,
+ private val errorFormatter: ErrorFormatter
) : TypedEpoxyController() {
var listener: Listener? = null
@@ -58,13 +63,14 @@ class LocalePickerController @Inject constructor(
title(host.stringProvider.getString(R.string.choose_locale_other_locales_title))
}
when (list) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("loading")
loadingText(host.stringProvider.getString(R.string.choose_locale_loading_locales))
}
}
- is Success ->
+ is Success ->
if (list().isEmpty()) {
noResultItem {
id("noResult")
@@ -84,6 +90,11 @@ class LocalePickerController @Inject constructor(
}
}
}
+ is Fail ->
+ errorWithRetryItem {
+ id("error")
+ text(host.errorFormatter.toHumanReadable(list.error))
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt
index 601574c908..d46b66dd87 100644
--- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt
@@ -26,7 +26,6 @@ import com.airbnb.mvrx.withState
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.restart
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentLocalePickerBinding
@@ -54,7 +53,7 @@ class LocalePickerFragment @Inject constructor(
LocalePickerViewEvents.RestartActivity -> {
activity?.restart()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt
index d6b35fa4fe..0bbbc323e0 100644
--- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.configuration.VectorConfiguration
import im.vector.app.features.settings.VectorLocale
@@ -56,7 +55,7 @@ class LocalePickerViewModel @AssistedInject constructor(
override fun handle(action: LocalePickerAction) {
when (action) {
is LocalePickerAction.SelectLocale -> handleSelectLocale(action)
- }.exhaustive
+ }
}
private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt
index 65c62542bb..73a74b1e3f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt
@@ -28,7 +28,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentGenericRecyclerBinding
import org.matrix.android.sdk.api.session.pushers.Pusher
@@ -78,7 +77,7 @@ class PushGatewaysFragment @Inject constructor(
.setPositiveButton(android.R.string.ok, null)
.show()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt
index 1256673364..4d95447f2d 100644
--- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
@@ -65,7 +64,7 @@ class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState:
when (action) {
is PushGatewayAction.Refresh -> handleRefresh()
is PushGatewayAction.RemovePusher -> removePusher(action.pusher)
- }.exhaustive
+ }
}
private fun removePusher(pusher: Pusher) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
index d374357396..61d93b6f5f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
@@ -21,11 +21,11 @@ import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.core.epoxy.loadingItem
import im.vector.app.core.epoxy.noResultItem
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.getFormattedValue
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
@@ -78,6 +78,7 @@ class ThreePidsSettingsController @Inject constructor(
}
when (data.threePids) {
+ Uninitialized,
is Loading -> {
loadingItem {
id("loading")
@@ -160,7 +161,7 @@ class ThreePidsSettingsController @Inject constructor(
}
}
is ThreePidsSettingsUiState.AddingPhoneNumber -> Unit
- }.exhaustive
+ }
settingsSectionTitleItem {
id("msisdn")
@@ -223,7 +224,7 @@ class ThreePidsSettingsController @Inject constructor(
cancelOnClick { host.interactionListener?.cancelAdding() }
}
}
- }.exhaustive
+ }
}
private fun buildThreePid(idPrefix: String, threePid: ThreePid) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt
index bdb1fb895f..ee7f8efab4 100644
--- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt
@@ -28,7 +28,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.getFormattedValue
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.isEmail
@@ -64,7 +63,7 @@ class ThreePidsSettingsFragment @Inject constructor(
when (it) {
is ThreePidsSettingsViewEvents.Failure -> displayErrorDialog(it.throwable)
is ThreePidsSettingsViewEvents.RequestReAuth -> askAuthentication(it)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt
index 12ff436ccb..acbe893d58 100644
--- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.ReadOnceTrue
@@ -149,7 +148,7 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
uiaContinuation = null
pendingAuth = null
}
- }.exhaustive
+ }
}
var uiaContinuation: Continuation? = null
diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt
index 62fb064536..9dc433e96f 100644
--- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt
@@ -34,7 +34,6 @@ import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentIncomingShareBinding
@@ -81,7 +80,7 @@ class IncomingShareFragment @Inject constructor(
is IncomingShareViewEvents.ShareToRoom -> handleShareToRoom(it)
is IncomingShareViewEvents.EditMediaBeforeSending -> handleEditMediaBeforeSending(it)
is IncomingShareViewEvents.MultipleRoomsShareDone -> handleMultipleRoomsShareDone(it)
- }.exhaustive
+ }
}
val intent = vectorBaseActivity.intent
diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt
index 4a413ad8ba..ca4148ebb7 100644
--- a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.toggle
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.attachments.isPreviewable
@@ -96,7 +95,7 @@ class IncomingShareViewModel @AssistedInject constructor(
is IncomingShareAction.ShareMedia -> handleShareMediaToSelectedRooms(action)
is IncomingShareAction.FilterWith -> handleFilter(action)
is IncomingShareAction.UpdateSharedData -> handleUpdateSharedData(action)
- }.exhaustive
+ }
}
private fun handleUpdateSharedData(action: IncomingShareAction.UpdateSharedData) {
@@ -127,7 +126,7 @@ class IncomingShareViewModel @AssistedInject constructor(
is SharedData.Attachments -> {
shareAttachments(sharedData.attachmentData, state.selectedRoomIds, proposeMediaEdition = true, compressMediaBeforeSending = false)
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
index 0cd9cde547..e2f3c14e7d 100644
--- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
+++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
@@ -18,8 +18,9 @@ package im.vector.app.features.signout.soft
import com.airbnb.epoxy.EpoxyController
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.core.epoxy.loadingItem
import im.vector.app.core.error.ErrorFormatter
@@ -89,19 +90,20 @@ class SoftLogoutController @Inject constructor(
private fun buildForm(state: SoftLogoutViewState) {
val host = this
when (state.asyncHomeServerLoginFlowRequest) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("loading")
}
}
- is Fail -> {
+ is Fail -> {
loginErrorWithRetryItem {
id("errorRetry")
text(host.errorFormatter.toHumanReadable(state.asyncHomeServerLoginFlowRequest.error))
listener { host.listener?.retry() }
}
}
- is Success -> {
+ is Success -> {
when (state.asyncHomeServerLoginFlowRequest.invoke()) {
LoginMode.Password -> {
loginPasswordFormItem {
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt
index dff98722eb..1fc131ca86 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt
@@ -22,13 +22,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.airbnb.epoxy.EpoxyTouchHelper
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.StateView
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentGroupListBinding
@@ -109,7 +109,7 @@ class SpaceListFragment @Inject constructor(
is SpaceListViewEvents.AddSpace -> sharedActionViewModel.post(HomeActivitySharedAction.AddSpace)
is SpaceListViewEvents.OpenGroup -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup(it.groupingMethodHasChanged))
is SpaceListViewEvents.OpenSpaceInvite -> sharedActionViewModel.post(HomeActivitySharedAction.OpenSpaceInvite(it.id))
- }.exhaustive
+ }
}
}
@@ -121,8 +121,10 @@ class SpaceListFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state ->
when (state.asyncSpaces) {
- is Incomplete -> views.stateView.state = StateView.State.Loading
- is Success -> views.stateView.state = StateView.State.Content
+ Uninitialized,
+ is Loading -> views.stateView.state = StateView.State.Loading
+ is Success -> views.stateView.state = StateView.State.Content
+ else -> Unit
}
spaceController.update(state)
}
diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt
index 8ddeab3223..2b8276a4d7 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt
@@ -29,7 +29,6 @@ import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.isEmail
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@@ -192,7 +191,7 @@ class CreateSpaceViewModel @AssistedInject constructor(
is CreateSpaceAction.SetSpaceTopology -> {
handleSetTopology(action)
}
- }.exhaustive
+ }
}
private fun handleSetTopology(action: CreateSpaceAction.SetSpaceTopology) {
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt
index 85f80960b0..12ae8fc1f9 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt
@@ -85,6 +85,7 @@ class SpaceManageActivity : VectorBaseActivity() {
when (sharedAction) {
is RoomDirectorySharedAction.Back,
is RoomDirectorySharedAction.Close -> finish()
+ else -> Unit
}
}
.launchIn(lifecycleScope)
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt
index bedd1873e8..2a2598075f 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt
@@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import org.matrix.android.sdk.api.session.Session
@@ -51,6 +50,6 @@ class SpaceManageSharedViewModel @AssistedInject constructor(
SpaceManagedSharedAction.ManageRooms -> _viewEvents.post(SpaceManagedSharedViewEvents.NavigateToManageRooms)
SpaceManagedSharedAction.OpenSpaceAliasesSettings -> _viewEvents.post(SpaceManagedSharedViewEvents.NavigateToAliasSettings)
SpaceManagedSharedAction.OpenSpacePermissionSettings -> _viewEvents.post(SpaceManagedSharedViewEvents.NavigateToPermissionSettings)
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt
index 266d08fd12..db9420abc2 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt
@@ -34,7 +34,6 @@ import im.vector.app.R
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment
@@ -102,7 +101,7 @@ class SpaceSettingsFragment @Inject constructor(
ignoreChanges = true
vectorBaseActivity.onBackPressed()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt
index 55d1dbe61e..2e386697d4 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt
@@ -25,7 +25,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.raw.wellknown.getElementWellknown
import im.vector.app.features.raw.wellknown.isE2EByDefault
@@ -52,7 +51,7 @@ class SpacePeopleViewModel @AssistedInject constructor(
when (action) {
is SpacePeopleViewAction.ChatWith -> handleChatWith(action)
SpacePeopleViewAction.InviteToSpace -> handleInviteToSpace()
- }.exhaustive
+ }
}
private fun handleInviteToSpace() {
diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt
index e6071fdd2a..9a86e550a8 100644
--- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt
@@ -23,7 +23,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.SimpleFragmentActivity
import org.matrix.android.sdk.api.session.terms.TermsService
@@ -63,7 +62,7 @@ class ReviewTermsActivity : SimpleFragmentActivity() {
setResult(Activity.RESULT_OK)
finish()
}
- }.exhaustive
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt
index cb76e5b31f..53afbf7a07 100644
--- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt
@@ -29,7 +29,6 @@ import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.openUrlInChromeCustomTab
import im.vector.app.databinding.FragmentReviewTermsBinding
@@ -70,7 +69,7 @@ class ReviewTermsFragment @Inject constructor(
ReviewTermsViewEvents.Success -> {
// Handled by the Activity
}
- }.exhaustive
+ }
}
reviewTermsViewModel.handle(ReviewTermsAction.LoadTerms(getString(R.string.resources_language)))
diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt
index 9932efb11a..8fe1f598f6 100644
--- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt
@@ -24,7 +24,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
@@ -49,7 +48,7 @@ class ReviewTermsViewModel @AssistedInject constructor(
is ReviewTermsAction.LoadTerms -> loadTerms(action)
is ReviewTermsAction.MarkTermAsAccepted -> markTermAsAccepted(action)
ReviewTermsAction.Accept -> acceptTerms()
- }.exhaustive
+ }
}
private fun markTermAsAccepted(action: ReviewTermsAction.MarkTermAsAccepted) = withState { state ->
diff --git a/vector/src/main/java/im/vector/app/features/terms/TermsController.kt b/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
index 6109e9abc8..10238829b3 100644
--- a/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
+++ b/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
@@ -17,8 +17,9 @@ package im.vector.app.features.terms
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
+import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
import im.vector.app.R
import im.vector.app.core.epoxy.errorWithRetryItem
import im.vector.app.core.epoxy.loadingItem
@@ -38,19 +39,20 @@ class TermsController @Inject constructor(
val host = this
when (data.termsList) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
loadingItem {
id("loading")
}
}
- is Fail -> {
+ is Fail -> {
errorWithRetryItem {
id("errorRetry")
text(host.errorFormatter.toHumanReadable(data.termsList.error))
listener { host.listener?.retry() }
}
}
- is Success -> buildTerms(data.termsList.invoke())
+ is Success -> buildTerms(data.termsList.invoke())
}
}
@@ -67,7 +69,7 @@ class TermsController @Inject constructor(
description(host.description)
checked(term.accepted)
- clickListener { host.listener?.review(term) }
+ clickListener { host.listener?.review(term) }
checkChangeListener { _, isChecked ->
host.listener?.setChecked(term, isChecked)
}
diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
index 356893aee2..9e0aa15297 100644
--- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt
@@ -30,7 +30,6 @@ import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.onPermissionDeniedSnackbar
@@ -127,7 +126,7 @@ class UserCodeActivity : VectorBaseActivity(),
Toast.makeText(this, R.string.qr_code_not_scanned, Toast.LENGTH_SHORT).show()
finish()
}
- }.exhaustive
+ }
}
}
@@ -153,7 +152,7 @@ class UserCodeActivity : VectorBaseActivity(),
UserCodeState.Mode.SHOW -> super.onBackPressed()
is UserCodeState.Mode.RESULT,
UserCodeState.Mode.SCAN -> sharedViewModel.handle(UserCodeActions.SwitchMode(UserCodeState.Mode.SHOW))
- }.exhaustive
+ }
}
companion object {
diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt
index 64bcf9cead..da894a42be 100644
--- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt
@@ -62,12 +62,12 @@ class UserCodeSharedViewModel @AssistedInject constructor(
override fun handle(action: UserCodeActions) {
when (action) {
- UserCodeActions.DismissAction -> _viewEvents.post(UserCodeShareViewEvents.Dismiss)
- is UserCodeActions.SwitchMode -> setState { copy(mode = action.mode) }
- is UserCodeActions.DecodedQRCode -> handleQrCodeDecoded(action)
- is UserCodeActions.StartChattingWithUser -> handleStartChatting(action)
+ UserCodeActions.DismissAction -> _viewEvents.post(UserCodeShareViewEvents.Dismiss)
+ is UserCodeActions.SwitchMode -> setState { copy(mode = action.mode) }
+ is UserCodeActions.DecodedQRCode -> handleQrCodeDecoded(action)
+ is UserCodeActions.StartChattingWithUser -> handleStartChatting(action)
is UserCodeActions.CameraPermissionNotGranted -> _viewEvents.post(UserCodeShareViewEvents.CameraPermissionNotGranted(action.deniedPermanently))
- UserCodeActions.ShareByText -> handleShareByText()
+ UserCodeActions.ShareByText -> handleShareByText()
}
}
@@ -110,11 +110,11 @@ class UserCodeSharedViewModel @AssistedInject constructor(
_viewEvents.post(UserCodeShareViewEvents.ShowWaitingScreen)
viewModelScope.launch(Dispatchers.IO) {
when (linkedId) {
- is PermalinkData.RoomLink -> {
+ is PermalinkData.RoomLink -> {
// not yet supported
_viewEvents.post(UserCodeShareViewEvents.ToastMessage(stringProvider.getString(R.string.not_implemented)))
}
- is PermalinkData.UserLink -> {
+ is PermalinkData.UserLink -> {
val user = tryOrNull { session.resolveUser(linkedId.userId) }
// Create raw Uxid in case the user is not searchable
?: User(linkedId.userId, null, null)
@@ -125,14 +125,15 @@ class UserCodeSharedViewModel @AssistedInject constructor(
)
}
}
- is PermalinkData.GroupLink -> {
+ is PermalinkData.GroupLink -> {
// not yet supported
_viewEvents.post(UserCodeShareViewEvents.ToastMessage(stringProvider.getString(R.string.not_implemented)))
}
- is PermalinkData.FallbackLink -> {
+ is PermalinkData.FallbackLink -> {
// not yet supported
_viewEvents.post(UserCodeShareViewEvents.ToastMessage(stringProvider.getString(R.string.not_implemented)))
}
+ is PermalinkData.RoomEmailInviteLink -> Unit
}
_viewEvents.post(UserCodeShareViewEvents.HideWaitingScreen)
}
diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt
index 61f8bc35f3..039c7041b0 100644
--- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt
@@ -26,7 +26,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.isEmail
import im.vector.app.core.extensions.toggle
import im.vector.app.core.platform.VectorViewModel
@@ -113,7 +112,7 @@ class UserListViewModel @AssistedInject constructor(
UserListAction.UserConsentRequest -> handleUserConsentRequest()
is UserListAction.UpdateUserConsent -> handleISUpdateConsent(action)
UserListAction.Resumed -> handleResumed()
- }.exhaustive
+ }
}
private fun handleUserConsentRequest() {
diff --git a/vector/src/main/java/im/vector/app/features/voice/AudioWaveformView.kt b/vector/src/main/java/im/vector/app/features/voice/AudioWaveformView.kt
new file mode 100644
index 0000000000..32f30fe458
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/voice/AudioWaveformView.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2022 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.features.voice
+
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.util.AttributeSet
+import android.view.View
+import im.vector.app.R
+import kotlin.math.max
+import kotlin.random.Random
+
+class AudioWaveformView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : View(context, attrs, defStyleAttr) {
+
+ private enum class Alignment(var value: Int) {
+ CENTER(0),
+ BOTTOM(1),
+ TOP(2)
+ }
+
+ private enum class Flow(var value: Int) {
+ LTR(0),
+ RTL(1)
+ }
+
+ data class FFT(val value: Float, var color: Int)
+
+ private fun Int.dp() = this * Resources.getSystem().displayMetrics.density
+
+ // Configuration fields
+ private var alignment = Alignment.CENTER
+ private var flow = Flow.LTR
+ private var verticalPadding = 4.dp()
+ private var horizontalPadding = 4.dp()
+ private var barWidth = 2.dp()
+ private var barSpace = 1.dp()
+ private var barMinHeight = 1.dp()
+ private var isBarRounded = true
+
+ private val rawFftList = mutableListOf()
+ private var visibleBarHeights = mutableListOf()
+
+ private val barPaint = Paint()
+
+ init {
+ attrs?.let {
+ context
+ .theme
+ .obtainStyledAttributes(
+ attrs,
+ R.styleable.AudioWaveformView,
+ 0,
+ 0
+ )
+ .apply {
+ alignment = Alignment.values().find { it.value == getInt(R.styleable.AudioWaveformView_alignment, alignment.value) }!!
+ flow = Flow.values().find { it.value == getInt(R.styleable.AudioWaveformView_flow, alignment.value) }!!
+ verticalPadding = getDimension(R.styleable.AudioWaveformView_verticalPadding, verticalPadding)
+ horizontalPadding = getDimension(R.styleable.AudioWaveformView_horizontalPadding, horizontalPadding)
+ barWidth = getDimension(R.styleable.AudioWaveformView_barWidth, barWidth)
+ barSpace = getDimension(R.styleable.AudioWaveformView_barSpace, barSpace)
+ barMinHeight = getDimension(R.styleable.AudioWaveformView_barMinHeight, barMinHeight)
+ isBarRounded = getBoolean(R.styleable.AudioWaveformView_isBarRounded, isBarRounded)
+ setWillNotDraw(false)
+ barPaint.isAntiAlias = true
+ }
+ .apply { recycle() }
+ .also {
+ barPaint.strokeWidth = barWidth
+ barPaint.strokeCap = if (isBarRounded) Paint.Cap.ROUND else Paint.Cap.BUTT
+ }
+ }
+ }
+
+ fun initialize(fftList: List) {
+ handleNewFftList(fftList)
+ invalidate()
+ }
+
+ fun add(fft: FFT) {
+ handleNewFftList(listOf(fft))
+ invalidate()
+ }
+
+ fun summarize() {
+ if (rawFftList.isEmpty()) return
+
+ val maxVisibleBarCount = getMaxVisibleBarCount()
+ val summarizedFftList = rawFftList.summarize(maxVisibleBarCount)
+ clear()
+ handleNewFftList(summarizedFftList)
+ invalidate()
+ }
+
+ fun updateColors(limitPercentage: Float, colorBefore: Int, colorAfter: Int) {
+ val size = visibleBarHeights.size
+ val limitIndex = (size * limitPercentage).toInt()
+ visibleBarHeights.forEachIndexed { index, fft ->
+ fft.color = if (index < limitIndex) {
+ colorBefore
+ } else {
+ colorAfter
+ }
+ }
+ invalidate()
+ }
+
+ fun clear() {
+ rawFftList.clear()
+ visibleBarHeights.clear()
+ }
+
+ private fun List.summarize(target: Int): List {
+ flow = Flow.LTR
+ val result = mutableListOf()
+ if (size <= target) {
+ result.addAll(this)
+ val missingItemCount = target - size
+ repeat(missingItemCount) {
+ val index = Random.nextInt(result.size)
+ result.add(index, result[index])
+ }
+ } else {
+ val step = (size.toDouble() - 1) / (target - 1)
+ var index = 0.0
+ while (index < size) {
+ result.add(get(index.toInt()))
+ index += step
+ }
+ }
+ return result
+ }
+
+ private fun handleNewFftList(fftList: List) {
+ val maxVisibleBarCount = getMaxVisibleBarCount()
+ fftList.forEach { fft ->
+ rawFftList.add(fft)
+ val barHeight = max(fft.value / MAX_FFT * (height - verticalPadding * 2), barMinHeight)
+ visibleBarHeights.add(FFT(barHeight, fft.color))
+ if (visibleBarHeights.size > maxVisibleBarCount) {
+ visibleBarHeights = visibleBarHeights.subList(visibleBarHeights.size - maxVisibleBarCount, visibleBarHeights.size)
+ }
+ }
+ }
+
+ private fun getMaxVisibleBarCount() = ((width - horizontalPadding * 2) / (barWidth + barSpace)).toInt()
+
+ private fun drawBars(canvas: Canvas) {
+ var currentX = horizontalPadding
+ val flowableBarHeights = if (flow == Flow.LTR) visibleBarHeights else visibleBarHeights.reversed()
+
+ flowableBarHeights.forEach {
+ barPaint.color = it.color
+ when (alignment) {
+ Alignment.BOTTOM -> {
+ val startY = height - verticalPadding
+ val stopY = startY - it.value
+ canvas.drawLine(currentX, startY, currentX, stopY, barPaint)
+ }
+ Alignment.CENTER -> {
+ val startY = (height - it.value) / 2
+ val stopY = startY + it.value
+ canvas.drawLine(currentX, startY, currentX, stopY, barPaint)
+ }
+ Alignment.TOP -> {
+ val startY = verticalPadding
+ val stopY = startY + it.value
+ canvas.drawLine(currentX, startY, currentX, stopY, barPaint)
+ }
+ }
+ currentX += barWidth + barSpace
+ }
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+ drawBars(canvas)
+ }
+
+ companion object {
+ const val MAX_FFT = 32760
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
index 963bd9521c..77ec4c5b06 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt
@@ -80,6 +80,7 @@ class WidgetActivity : VectorBaseActivity() {
viewModel.observeViewEvents {
when (it) {
is WidgetViewEvents.Close -> handleClose(it)
+ else -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt
index 8fa9e07848..dbd63186b6 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt
@@ -29,7 +29,6 @@ import android.view.ViewGroup
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.Incomplete
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
@@ -87,6 +86,7 @@ class WidgetFragment @Inject constructor() :
is WidgetViewEvents.OnURLFormatted -> loadFormattedUrl(it)
is WidgetViewEvents.DisplayIntegrationManager -> displayIntegrationManager(it)
is WidgetViewEvents.Failure -> displayErrorDialog(it.throwable)
+ is WidgetViewEvents.Close -> Unit
}
}
viewModel.handle(WidgetAction.LoadFormattedUrl)
@@ -192,13 +192,14 @@ class WidgetFragment @Inject constructor() :
override fun invalidate() = withState(viewModel) { state ->
Timber.v("Invalidate state: $state")
when (state.formattedURL) {
- is Incomplete -> {
+ Uninitialized,
+ is Loading -> {
setStateError(null)
views.widgetWebView.isInvisible = true
views.widgetProgressBar.isIndeterminate = true
views.widgetProgressBar.isVisible = true
}
- is Success -> {
+ is Success -> {
setStateError(null)
when (state.webviewLoadedUrl) {
Uninitialized -> {
@@ -221,7 +222,7 @@ class WidgetFragment @Inject constructor() :
}
}
}
- is Fail -> {
+ is Fail -> {
// we need to show Error
views.widgetWebView.isInvisible = true
views.widgetProgressBar.isVisible = false
diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt
index f29e6d1928..78871da324 100644
--- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt
@@ -93,6 +93,7 @@ class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val in
when (action) {
RoomWidgetPermissionActions.AllowWidget -> handleAllowWidget()
RoomWidgetPermissionActions.BlockWidget -> handleRevokeWidget()
+ RoomWidgetPermissionActions.DoClose -> Unit
}
}
diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt
index 4daaef6fe1..fbc0b8fcff 100644
--- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt
@@ -28,7 +28,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.platform.VectorViewModelAction
@@ -124,7 +123,7 @@ class SignoutCheckViewModel @AssistedInject constructor(
copy(hasBeenExportedToFile = Success(true))
}
}
- }.exhaustive
+ }
}
private fun handleExportKeys(action: Actions.ExportKeys) {
diff --git a/vector/src/main/res/layout/item_timeline_event_voice_stub.xml b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml
index a180afbf8e..0fad714bd4 100644
--- a/vector/src/main/res/layout/item_timeline_event_voice_stub.xml
+++ b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml
@@ -40,7 +40,7 @@
app:layout_constraintTop_toTopOf="@id/voicePlaybackControlButton"
tools:text="0:23" />
-
-
-
@@ -59,27 +48,50 @@
tools:ignore="MissingConstraints"
tools:visibility="invisible" />
+
+
+ app:constraint_referenced_ids="roomToolbarAvatarImageView,roomToolbarAvatarShield,roomToolbarPresenceImageView,roomToolbarPublicImageView" />
+
+
- فشلت إزالة الودجة
فشلت إضافة الودجة
يستمع للإشعارات
+ ينتظر…
+ تفاعلَ بـ: %s
+ استبيان
+ ملصق
+ ملف
+ تسجيل صوتي
+ صوت
+ صورة.
+ فيديو.
+ ليس آمن
+ ينشئ فضاءً…
+ فشل إرسال الاقتراح (%s)
+ شكرًا، أُرسل اقتراحك
+ صِف اقتراحك
+ اكتب اقتراحك أدناه.
+ إعدادات النظام
+ احصل على المساعدة باستخدام ${app_name}
+ الصوت والفيديو
+ الأمان والخصوصية
+ الخيارات
+ عام
+ "أُنشئت الغرفة، لكن فشل إرسال بعض الدعوات بسبب:
+\n
+\n%s"
+ يمكن لأي شخص الإنضمام لهذه الغرفة
+ علنية
+ إعدادات الغرفة
+ الموضوع
+ موضوع الغرفة (اختياري)
+ الاسم
+ اسم الغرفة
+ أنشئ
+ رسالة مباشرة
+ الغرف
+ لا يمكنك معاينة هذه الغرفة، هل تريد الإنضمام إليها؟
+ لا يمكنك الوصول إلى هذه الغرفة حاليًا.
+\nحاول لاحقًا، أو اسأل مدير الغرفة إن كان لديك نفاذ لها.
+ تتعذر معاية هذه الغرفة
+ كل المجتمعات
+ رجاء انتظر…
+ غيّر الشبكة
+ أنشئ فضاء جديد
+ أنشئ غرفة جديدة
+ حدث حذفه مستخدم
+ اعرض الرسائل المحذوفة
+ حُذفت الرسالة
+ الانفعالات
+ اعرض الانفعالات
+ أضف انفعالًا
+ الانفعالات
\ No newline at end of file
diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml
index cf022172c2..c7e0f96433 100644
--- a/vector/src/main/res/values-cs/strings.xml
+++ b/vector/src/main/res/values-cs/strings.xml
@@ -932,7 +932,7 @@
Opakovat
Poslali Vám pozvánku
%s Vás pozval
- Vše jste dohnali!
+ To je všechno!
Nemáte již žádné nepřečtené zprávy
Konverzace
Tady budou zobrazeny Vaše přímé konverzace. Pro novou zprávu klepněte na + vpravo dole.
diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml
index 7a8ac9c71b..4c5131d452 100644
--- a/vector/src/main/res/values-de/strings.xml
+++ b/vector/src/main/res/values-de/strings.xml
@@ -1079,7 +1079,7 @@
Erweitere und individualisiere dein Benutzererlebnis
Mit %1$s verbinden
Mit Element Matrix Services verbinden
- Mit einem individuellen Server verbinden
+ Mit einem anderen Server verbinden
Bei %1$s anmelden
Registrieren
Anmelden
@@ -1257,7 +1257,7 @@
Raum verlassen
Verlasse den Raum…
Administratoren
- Moderationen
+ Moderatoren
Benutzerdefiniert
Eingeladen
Nutzer
@@ -2380,7 +2380,7 @@
Organisiere Diskussionen mit Threads
Threads im Raum filtern
Möchtest du einem existierenden Server beitreten\?
- Communities
+ Gemeinschaften
Teams
Wir helfen dir, in Verbindung zu kommen.
Mit wem wirst du am meisten chatten\?
diff --git a/vector/src/main/res/values-el/strings.xml b/vector/src/main/res/values-el/strings.xml
index fb4956444a..a7da13bdb3 100644
--- a/vector/src/main/res/values-el/strings.xml
+++ b/vector/src/main/res/values-el/strings.xml
@@ -1,7 +1,6 @@
Ηλεκτρονική διεύθυνση
-
Ο/Η %1$s σας προσκάλεσε
Ο/Η %1$s αποχώρησε
Ο/Η %1$s απέρριψε την πρόσκληση
@@ -9,7 +8,6 @@
Ο/Η %1$s προσκάλεσε τον/την %2$s
Η πρόσκληση του/της %s
Αριθμός τηλεφώνου
-
Ο/Η %1$s απέκλεισε τον/την %2$s
Ο/Η %1$s απέσυρε την πρόσκληση του/της %2$s
Ο/Η %1$s άλλαξε εικονίδιο χρήστη
@@ -20,7 +18,6 @@
Ο/Η %1$s άλλαξε το όνομα του δωματίου σε: %2$s
Ο/Η %s απάντησε στην κλήση.
Ο/Η %s τερμάτισε την κλήση.
-
Ο/Η %s πραγματοποίησε μια κλήση βίντεο.
Ο/Η %s πραγματοποίησε μια κλήση ήχου.
Ο/Η %1$s κατέστησε το μελλοντικό ιστορικό του δωματίου ορατό στον/στην %2$s
@@ -31,28 +28,15 @@
Ο/Η %1$s αφαίρεσε το όνομα του δωματίου
Ο/Η %1$s αφαίρεσε το θέμα του δωματίου
Ο/Η %1$s δέχτηκε την πρόσκληση για το %2$s
-
** Αδυναμία αποκρυπτογράφησης: %s **
Η συσκευή του/της αποστολέα δεν μας έχει στείλει τα κλειδιά για αυτό το μήνυμα.
-
Αποτυχία αποστολής μηνύματος
-
-
Σφάλμα του Matrix
-
-
Ο/Η %1$s εισήλθε στο δωμάτιο
-
Πρόσκληση στο δωμάτιο
-
%1$s και %2$s
-
-
-
Άδειο δωμάτιο
-
όλα τα μέλη του δωματίου από την στιγμή που εισήλθαν.
-
Ο/Η %1$s έστειλε μία πρόσκληση στον/στην %2$s για να εισέλθει στο δωμάτιο
Ακύρωση
Κλείσιμο
@@ -108,7 +92,6 @@
Μόνο οι επαφές Matrix
Δεν βρέθηκαν αποτελέσματα
Δωμάτια
-
Κοινότητες
Αποστολή καταγραφών σφαλμάτων
Αναφορά σφάλματος
@@ -214,8 +197,6 @@
Σφάλμα εντολής
Δημιουργία
Δωμάτια
-
-
Λόγος: %1$s
Απενεργοποίηση λογαριασμού
Απενεργοποίηση λογαριασμού
@@ -295,7 +276,6 @@
- %d πρόσκληση
- %d προσκλήσεις
-
Σύνδεση
Λόγος οριστικής αποβολής
Αποκλεισμός χρήστη
@@ -353,7 +333,6 @@
Αποτυχία σύνδεσης σε πραγματικό χρόνο.
\nΖητήστε από τον διαχειριστή του οικιακού σας διακομιστή να διαμορφώσει έναν διακομιστή TURN ώστε οι κλήσεις να λειτουργούν αξιόπιστα.
Η Κλήση ${app_name} Aπέτυχε
-
Είσαστε σίγουροι ότι θέλετε να κάνετε κλήση βίντεο;
Είσαστε σίγουροι ότι θέλετε να κάνετε κλήση ήχου;
Αποστολή φωνής
@@ -369,7 +348,6 @@
Κατάργηση δημοσίευσης
Αντιγραφή
Τέλος κλήσης
-
Ειδοποιήσεις
Αντιγράφηκε στο πρόχειρο
Πρόσθεση
@@ -392,7 +370,6 @@
%s γράφει…
%1$s & %2$s γράφουν…
Δεν εξακριβώθηκε η ταυτότητα του εξωτερικού διακομιστή.
-
Κανένα αποτέλεσμα
Φιλτράρισμα αποβεβλημένων χρηστών
Φιλτράρισμα μελών δωματίου
@@ -402,4 +379,9 @@
Το πιστοποιητικό έχει αλλάξει από αυτό που εμπιστεύθηκε προηγουμένως η συσκευή σας. Αυτό είναι ΑΚΡΩΣ ΑΣΥΝΗΘΙΣΤΟ. Προτείνεται να ΜΗΝ ΑΠΟΔΕΚΤΕΙΤΕ το νεο πιστοποιητικό.
Προεπιλογή Συστήματος
Λανθασμένο όνομα χρήστη και/ή κωδικού
+ Τερματισμός δημοσκόπησης
+ Επεξεργασία δημοσκόπησης
+ Άνοιγμα με
+ Αποστολή αυτοκόλλητου
+ %1$s δημιούργησε το δωμάτιο
\ No newline at end of file
diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml
index 8e0568e7ae..0f80bc8e0f 100644
--- a/vector/src/main/res/values-es/strings.xml
+++ b/vector/src/main/res/values-es/strings.xml
@@ -39,7 +39,6 @@
Invitación a Sala
%1$s y %2$s
Sala vacía
-
%1$s ha revocado la invitación a unirse a la sala para %2$s
Sincronización inicial
\nImportando cuenta…
@@ -241,7 +240,6 @@
Eliminar
Renombrar
Reportar contenido
-
o
Invitar
Cerrar sesión
@@ -264,7 +262,6 @@
Solo contactos de Matrix
No hay resultados
Salas
-
Enviar registros
Enviar registros de fallas
Enviar captura de pantalla
@@ -292,11 +289,9 @@
Esto no parece ser una dirección de correo electrónico válida
Esta dirección de correo electrónico ya está definida.
¿Olvidaste tu contraseña?
-
Este Servidor Doméstico quiere asegurarse de que no eres un robot
Debes ingresar la dirección de correo electrónico vinculada a tu cuenta.
No se pudo verificar la dirección de correo electrónico: asegúrate de hacer clic en el enlace del correo electrónico
-
Por favor introduce una URL válida
JSON mal formado
No contenía un JSON válido
@@ -312,15 +307,10 @@
Llamada En Curso…
El lado remoto no contestó.
Información
-
-
${app_name} necesita permiso para acceder a tu micrófono para realizar llamadas de voz.
-
${app_name} necesita permiso para acceder a tu cámara y micrófono para realizar llamadas de vídeo.
\n
\nPor favor permite el acceso en las próximas ventanas emergentes para poder realizar la llamada.
-
-
SÍ
NO
Continuar
@@ -328,7 +318,6 @@
Unirse
Rechazar
Mensajes no leídos.
-
Salir de la sala
¿Seguro que quieres salir de la sala?
CONVERSACIONES DIRECTAS
@@ -355,7 +344,6 @@
El certificado cambió de uno que era confiable para tu teléfono. Esto es MUY INUSUAL. Se recomienda NO ACEPTAR este nuevo certificado.
El certificado cambió de uno que era confiable a uno que no es confiable. El servidor puede haber renovado su certificado. Contacta al administrador del servidor para obtener la huella digital.
Solo acepta el certificado si el administrador del servidor ha publicado una huella digital que coincide con la anterior.
-
Buscar
Filtrar miembros de la sala
No hay resultados
@@ -400,7 +388,6 @@
Actualizar Nombre Público
Visto por última vez
%1$s @ %2$s
-
Autenticación
Sesión iniciada como
Servidor Doméstico
@@ -431,7 +418,6 @@
Estas son funcionalidades experimentales que pueden romperse de maneras inesperadas. Utilizar con precaución.
Establecer como dirección principal
Dejar de Establecer como dirección principal
-
Error de descifrado
Nombre público
ID de sesión
@@ -442,7 +428,6 @@
Exportar
Ingresar frase de contraseña
Confirmar frase de contraseña
-
Importar claves de salas con cifrado Extremo-a-Extremo
Importar claves de sala
Importar las claves desde un archivo local
@@ -454,7 +439,6 @@
Verificar
Para verificar que esta sesión es confiable, por favor contacta a su dueño por algún otro medio (ej. cara a cara o por teléfono) y pregúntale si la clave que ve en sus Ajustes de Usuario para esta sesión coincide con la clave a continuación:
Si coincide, presione el botón de verificar a continuación. Si no coincide, entonces alguien está interceptando esta sesión y probablemente debería prohibirlo. En el futuro, este proceso de verificación será más sofisticado.
-
Selecciona un directorio de salas
Nombre del servidor
Todas las salas en el servidor %s
@@ -540,8 +524,6 @@
- %d mensaje nuevo
- %d mensajes nuevos
-
-
- %d sala
- %d salas
@@ -550,12 +532,10 @@
- %d cambio de membresía
- %d cambios de membresía
-
- %d mensaje sin leer
- %d mensajes sin leer
-
%1$s en %2$s
- %d componente activo
@@ -608,16 +588,10 @@
Haz clic aquí para ver mensajes más antiguos
Degrada al usuario con la ID dada
Alertas de Sistema
-
-
-
-
- $d seleccionado
- %d seleccionados
-
-
contacta al administrador de tu servicio
Este servidor doméstico ha excedido uno de sus límites de recursos, por lo que algunos usuarios no podrán iniciar sesión.
Este servidor doméstico ha excedido uno de sus límites de recursos.
@@ -741,7 +715,6 @@
Incluye cambios en el avatar y en el nombre.
Enviar mensaje con intro
La tecla Intro enviará el mensaje en vez de añadir un salto de línea
-
Contraseña
La contraseña no es válida
Media
@@ -801,7 +774,6 @@
Guardar clave de recuperación
Compartir
Guardar como archivo
-
Por favor, haga una copia
Compartir clave de recuperación con…
Generando clave de recuperación usando una contraseña, este proceso puede tardar varios segundos.
@@ -848,7 +820,6 @@
- Cargando %d de las claves…
Firma
-
Origen predeterminado de medios
Configurar copia de seguridad de las claves de cifrado
Obteniendo una versión de copia de seguridad…
@@ -857,7 +828,6 @@
La copia de seguridad tiene una firma inválida de la sesión no verificada %s
Para usar la copia de seguridad de la clave en esta sesión introduzca su contraseña o su clave de recuperación ahora.
¿Deseas borrar tus claves de cifrado guardadas en el servidor\? No podrás usar tu clave de recuperación para leer el historial de mensajes cifrados.
-
Reproducir sonido de cámara
ip desconocida
Una nueva sesión solicita claves de cifrado.
@@ -878,8 +848,6 @@
Comprobando copias de respaldo
¡Verificado!
Ok
-
-
Solicitud de verificación
%s quiere verificar tu sesión
Error desconocido
@@ -933,7 +901,6 @@
Integraciones
Descubrimiento
Gestione sus preferencias de descubrimiento.
-
Esta no es una dirección de servidor Matrix válida
No se puede acceder al servidor en esta URL, por favor, compruébelo
Modo Sincronización en segundo plano
@@ -942,7 +909,6 @@
${app_name} se sincronizará en segundo plano periódicamente en un momento preciso (configurable).
\nEsto afectará al uso de la radio y la batería, se mostrará una notificación permanente que indica que ${app_name} está escuchando a nuevos acontecimientos.
No se le notificará de los mensajes entrantes cuando la aplicación esté en segundo plano.
-
Utiliza un Gestor de Integración para gestionar los bots, puentes, widgets y paquetes de pegatinas.
\nLos Gestores de Integración reciben los datos de configuración y pueden modificar los widgets, enviar invitaciones a salas y establecer niveles de poder en su nombre.
Permitir integraciones
@@ -1078,7 +1044,6 @@
Este contenido fue reportado como inapropiado.
\n
\nSi no quieres ver más contenido de este usuario, puedes bloquearlo para ocultar sus mensajes.
-
Ignorar usuario
Todos los mensajes (sonido)
Todos los mensajes
@@ -1508,7 +1473,6 @@
\n- El servidor privado al que está conectado el usuario que estás verificando
\n- Su conexión a internet o la de otros usuarios
\n- Su dispositivo o el de otros usuarios
-
Los mensajes de esta sala están cifrados Extremo-a-Extremo.
\n
\nSus mensajes están protegidos y sólo usted y el destinatario tienen las claves únicas para descifrarlos.
@@ -1589,7 +1553,6 @@
Imprímelo y guárdalo en un lugar seguro
Guárdelo en una llave USB o unidad de respaldo
Cópielo en su almacenamiento personal en la nube
-
Si cancela ahora, puede perder mensajes y datos cifrados si pierde el acceso a sus inicios de sesión.
\n
\nTambién puede configurar la Copia de Seguridad Segura y administrar sus claves en Configuración.
@@ -1937,7 +1900,6 @@
Transferir
Conectar
Preguntar primero
-
Llamada activa (%1$s)
Pad de marcado
Esta llamada ha terminado
@@ -2062,7 +2024,6 @@
Para llevar a cabo esta acción has de otorgar el permiso de Cámara en las preferencias del sistema.
Se requieren permisos para llevar a cabo esta acción. Por favor, otórgalos desde las preferencias del sistema.
Impedir a cualquiera que no forme parte de %s unirse a este sala
-
Dar consentimiento
Revocar consentimiento
Has dado tu consentimiento para enviar emails y números de teléfono a este servidor identidad para descubrir a otros usuarios desde tus contactos.
@@ -2087,7 +2048,6 @@
Actualización requerida
Actualizar
Por favor, se paciente. Ésto puede llevar algo de tiempo.
-
Sala sin nombre
Por favor, contacta con el administrador de tu homeserver para más información
Parece que tu homeserver no soporta Espacios todavía
@@ -2143,7 +2103,6 @@
Transferir a %1$s
Consultando con %1$s
Ocurrió un error al transferir la llamada
-
Hubo un error al buscar el número de teléfono
Devolver la llamada
Buscar contactos en Matrix
@@ -2312,4 +2271,37 @@
Ver en la sala
Habilitar
No estás autorizado a unirte a esta sala
+ ¿No lo sabes todavía\? Puedes %s
+ saltar esta pregunta
+ Comunidades
+ Equipos
+ Familia y amigos
+ Te vamos a ayudar a conectarte.
+ ¿Con quién hablarás más\?
+ Mensajería para tu equipo.
+ Mensajería segura.
+ Tú mandas.
+ Toma el control de tus conversaciones.
+ Ubicación
+ Encuesta
+ ¿Aceptas enviar esta información\?
+ Ajustes del sistema
+ Versiones
+ Obtén ayuda sobre cómo usar ${app_name}
+ Ayuda
+ Ayuda
+ Asuntos legales
+ ¡Ya estás viendo este hilo!
+ Ver en la sala
+ Responder en un hilo
+ El comando «%s» existe, pero no funciona dentro de hilos.
+ Este servidor no ha devuelto ninguna política.
+ Bibliotecas de terceros
+ Política de tu servidor de identidad
+ Política de tu servidor base
+ Política de ${app_name}
+ %1$s y %2$s
+ Filtrar
+ %1$s, %2$s y otros
+ Copiar enlace al hilo
\ No newline at end of file
diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml
index eb8a29b6b2..a3ee61013e 100644
--- a/vector/src/main/res/values-fa/strings.xml
+++ b/vector/src/main/res/values-fa/strings.xml
@@ -40,7 +40,6 @@
شماره تلفن
دعوت اتاق
%1$s و %2$s
-
اتاق خالی
همگامسازی نخستین:
\nدرونریزی حساب…
@@ -221,7 +220,6 @@
اولویت پایین
گفتگوها
اتاقها
-
گزارش اشکال
پیوستن به اتاق
نام کاربری
@@ -296,16 +294,11 @@
- %d عضو
- %d عضو
-
-
-
-
ترک اتاق
آیا از ترک این اتاق اطمینان دارید؟
گپهای مستقیم
دعوت
بارگیری
-
رد شدن
انجام شد
نادیدهگرفتن
@@ -327,7 +320,6 @@
در صورت عدم پشتیبانگیری از کلیدهای خود پیش از خروج، دسترسی شما به پیامهای رمزنگاری شده از بین میرود.
پیوند دائمی
مشاهده منبع رمزگشایی شده
-
این کارساز خانگی میخواهد مطمئن شود که روبات نیستید
بازدرخواست کلیدهای رمزنگاری از دیگر نشستهایتان.
لطفاً المنت را روی افزارهای دیگر که میتواند پیام را رمزگشایی کند، اجرا کنید تا بتواند کلیدها را به این نشست بفرستد.
@@ -335,8 +327,6 @@
قطع اتصال
نپذیرفتن
پالایش اعضای اتاق
-
-
عکس نمایه
نام نمایشی
افزودن نشانی رایانامه
@@ -419,7 +409,6 @@
افزودن کارههای ماتریکس
پیام رمزنگاری شده
اتاقها
-
(پیشرفته)
(پیشرفته) برپایی با کلید بازیابی
گرفتن نگارش پشتیبان…
@@ -518,7 +507,6 @@
ابطال
باید نشانی رایانامهٔ پیوسته به حسابتان وارد شود.
شکست در تأیید نشانی رایانامه: مطمئن شوید که پیوند درون رایانامه را کلیک کردهاید
-
لطفاً سیاستهای این کارساز خانگی را بررسی کرده و بپذیرید:
لطفا یک نشانی معتبر وارد کنید
این یک نشانی کارساز ماتریکس معتبر نیست
@@ -531,7 +519,6 @@
گزینش صدای زنگ برای تماسها:
اطلاعات
پرش به ناخوانده
-
تحریم
رفع انسداد
اخراج
@@ -722,7 +709,6 @@
- %d پیام آگاهی نخوانده
- %d پیام آگاهی نخوانده
-
- %1$s: %2$d پیام
- %1$s: %2$d پیام
@@ -796,7 +782,6 @@
ایجاد
خانه
دعوت شد
-
غیرفعّالسازی حساب
غیرفعّالسازی حساب
هرگز پیامهای رمزشده را از دست ندهید
@@ -1084,7 +1069,6 @@
گرفتم
اطّلاعات بیشتر
خطای رمزگشایی
-
بازنشاندن از نشانی اصلی
ارتباط با مدیر خدمتتان
اکنون بازبینی شود
@@ -1096,7 +1080,6 @@
رمزنگاری این اتاق پشتیبانی نمیشود
لطفاً نام کاربریای وارد کنید.
برای دیدن پیامهای قدیمیتر، کلیک کنید
-
پیامهای اینجا، رمزنگاری سرتاسری شدهاند.
\n
\nپیامهایتان با قفلهایی امن شدهاند و فقط شما و گیرندگان دیگر، کلیدهای یکتا را برای قفلگشاییشان دارید.
@@ -1215,7 +1198,6 @@
دعوتها، برداشتنها و انسدادها تأثیر نمیپذیرند.
نمایش پیامهای پیوستن و ترک اتاق
پیشنمایشی از آدرسهای URL در پیامها نمایش داده شود.
-
المنت بصورت دورهای و در بازههای قابل تنظیم در پس زمینه همگامسازی می شود.
\nاین بر مصرف باتری شما تأثیر میگذارد، یک اعلان دائمی نمایش داده میشود که المنت برای رویدادها گوش میدهد.
المنت در پس زمینه همگامسازی میکند به گونه ای که منابع محدود دستگاه (باتری) حفظ میشود.
@@ -1264,7 +1246,6 @@
هیچ شماره تلفنی به حسابتان افزوده نشده
نتیجهای در پی نداشت
فیلترکردن کاربران مسدود شده
-
- %d مورد
- %d مورد
@@ -1284,19 +1265,13 @@
تنزل نقش شما در اتاق؟
شما نمیتوانید این تغییر را بازگردانید. زیرا در حال ارتقای سطح کاربر دیگر به سطح خودتان هستید.
\nآیا مطمئن هستید؟
-
-
المنت برای برقراری تماس تصویری نیازمند دسترسی به میکروفون و دوربین است.
\n
\nلطفا در پنجره های بعدی دسترسی های لازم را بدهید.
-
المنت برای برقراری تماس صوتی نیازمند دسترسی به میکروفون است.
-
-
خطای SSL: هویت طرف مقابل تأیید نشد.
شکست در برقراری ارتباط همزمان.
\nلطاً از مدیر کارساز بخواهید برای برقراری مطمئن تماسها، کارساز turn را پیکربندی کند.
-
بعد از راهاندازی مجدد، هیچ تاریخچه، پیام، دستگاه تائید شده یا کاربر تائید شدهای در حساب شما وجود نخواهد داشت
اگر همه چیز را بازنشانی کنید
تنها در صورتی این کار را انجام دهید که از هیچ دستگاه دیگری نمیتوانید این دستگاه را تائید نمائید.
@@ -1319,7 +1294,6 @@
اگر اکنون لغو کنید، ممکن است در صورت قطع دسترسی به ورودهایتان، دادهها و پیامهای رمزنگاشته را از دست بدهد.
\n
\nهمچنین میتوانید در تنظیمات، پشتیبان امن برپا کرده و کلیدهایتان را مدیریت کنید.
-
آن را در فضای ابری خود کپی کنید
آن را روی فلش یا حافظهای دیگر ذخیره کنید
آن را چاپ کرده و در محلی امن و مطمئن نگهداری کنید
@@ -1478,7 +1452,6 @@
ارسال به عنوان پیام تباهکننده
حذفکردن از اولویت پایین
اضافهکردن به اولویت پایین
-
این محتوا به عنوان محتوای نامناسب گزارش شدهاست.
\n
\nاگر نمیخواهید محتوای بیشتری از این کاربر مشاهده کنید ، می توانید او را نادیده بگیرید تا پیامهای او را مشاهده نکنید.
@@ -1553,11 +1526,8 @@
خطای نامشخص
%s میخواهد نشستتان را تأیید کند
درخواست تأیید
-
-
فهمیدم
تأییدشده!
-
امضاء
الگوریتم
@@ -1568,7 +1538,6 @@
پشتیبانگیری از کلیدهای شما. این ممکن است چند دقیقه طول بکشد…
مدیریت در بخش پشتیبانگیری از کلید
کلیدهای رمزگذاری جدید
-
کلیدهای رمزگذاری پشتیبان شما از سرور حذف شوند؟ در اینن صورت دیگر نخواهید توانست از کلید بازیابی خود برای خواندن پیام رمزشدهی قبلی خود استفاده کنید.
حذف نسخهی پشتیبان
در حال بررسی وضعیت نسخهی پشتیبان
@@ -1609,7 +1578,6 @@
به نظر میرسد شما در یک نشست دیگر کلید پشتیبان تهیه کردهاید. آیا میخواهید آن را با موردی که ایجاد میکنید جایگزین کنید؟
از پیش، پشتیبانی روی کارساز خانگیتان وجود دارد
کلید بازیابی ذخیره شد.
-
کلید بازیابی خود را در جایی بسیار امن نظیر برنامههای شناختهشدهی مدیریت گذرواژه نگه دارید
کلید بازیابی شما برای روز مبادا است - اگر کلید امنیتی خود را فراموش کنید می توانید از آن برای بازیابی دسترسی به پیامهای رمزگذاری شده استفاده کنید.
\nکلید بازیابی خود را در جایی بسیار امن نظیر برنامههای شناختهشدهی مدیریت گذرواژه نگه دارید
@@ -1686,13 +1654,11 @@
- %d دعوت
نام کارساز
-
- %1$d از %2$d کلید با موفقیت بارگذاری شد.
- %1$d از %2$d کلید با موفقیت بارگذاری شدند.
کلیدها با موفقیت بر روی دستگاه استخراج شدند
-
لطفاً یک رمز برای رمزنگاری کلیدها وارد کنید. ورود این رمز برای بارگذاری کلیدها ضروری خواهد بود.
اجتماع
پخش صدای شاتر
@@ -1707,13 +1673,11 @@
لطفاً ایمیل خود را بررسی کنید و روی لینک ارسال شده، کلیک کنید. پس از انجام این کار، روی ادامه کلیک کنید.
برای انجام این کار اجازهی یکپارچهسازی را در تنظیمات فعال کنید.
یکپارچهسازیها غیر فعال هستند
-
%1$s @ %2$s
آخرین اتصال
نام عمومی
بهروزرسانی نام عمومی
شناسه
-
المنت اطلاعاتی را جمع آوری می کند و با ارسال آنان به صورت ناشناس به ما امکان بهبود برنامه را میدهد.
ارسال داده های تجزیه و تحلیل
تجزیه و تحلیل
@@ -1786,7 +1750,6 @@
آغاز به گپ
برونریزی بازرسی
اگر اتاق فقط برای تعامل با افراد داخل سرور خانه شما میباشد، این قابلیت را فعال کنید. این تنظیم را بعدا نمیتوانید تغییر دهید.
-
یک کلید امنیتی ایجاد کنید تا در مکانی امن مانند سامانه مدیریت رمز عبور یا گاوصندوق آن را ذخیره کنید.
ارتباطی با این شناسه وجود ندارد.
هویت خود را تأیید کنید تا به پیامهای رمز شده دسترسی پیدا کنید.
@@ -1872,8 +1835,6 @@
هنگام انتقال تماس خطایی روی داد
انتقال
متصل شوید
-
-
تماس فعال (%1$s)
هنگام جستجوی شماره تلفن خطایی روی داد
پد شماره گیری
@@ -2039,7 +2000,7 @@
من و همگروهیهایم
یک فضای خصوصی برای نظم بخشی به اتاقهایتان
فقط من
- مطمئن شوید که افراد درست به %s دسترسی دارند. میتوانید بعدها این را تغییر دهید.
+ مطمئن شوید که افراد درست به %s دسترسی دارند.
ساخت یک فضا
هر کسی در فضای این اتاق، میتواند اتاق را یافته و بپیوندد. فقط مدیران این اتاق می توانند به فضایی بیفزایندش.
فقط اعضای فضا
@@ -2123,7 +2084,6 @@
ارتقا
لطفاً شکیبا باشید. ممکن است کمی زمان ببرد.
پیوستن به اتاق جایگزینی
-
ناپایدار
پایدار
نگارش پیشگزیده
@@ -2313,7 +2273,6 @@
پرسش یا موضوع نظرسنجی
ایجاد نظرسنجی
نظرسنجی
-
فرستادن رایانامهّا و شمارههای تلفن به %s
آشنایانتان خصوصی هستند. برای کشف کاربران از آشنایانتان، نیاز به اجازهتان برای فرستادن اطّلاعات آشنا به کارساز هویتتان داریم.
نشست خارج شده است!
@@ -2446,4 +2405,18 @@
رونوشت از پیوند به رشته
دیدن در اتاق
دیدن رشتهها
+
+ - %d تغییر سطح کنترل دسترسی
+ - %d تغییر سطح کنترل دسترسی
+
+ آگاهی اتاق
+ کاربران
+ آگاهی به تمام اتاق
+
+ - %1$d بیشتر
+ - %1$d بیشتر
+
+ نمایش کمتر
+ %1$s، %2$s و دیگران
+ %1$s و %2$s
\ No newline at end of file
diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml
index 7e22ce42a8..c5e67771dd 100644
--- a/vector/src/main/res/values-fi/strings.xml
+++ b/vector/src/main/res/values-fi/strings.xml
@@ -46,7 +46,8 @@
Alkusynkronointi:
\nTuodaan huoneita
Alkusynkronointi:
-\nTuodaan liityttyjä huoneita
+\nLadataan keskustelujasi
+\nMikäli olet liittynyt moniin huoneisiin, tässä voi mennä tovi
Alkusynkronointi:
\nTuodaan kutsuttuja huoneita
Alkusynkronointi:
@@ -365,7 +366,7 @@
Kokeelliset
Nämä ovat kokeellisia ominaisuuksia, jotka voivat mennä rikki. Käytä varoen.
Aseta pääosoitteeksi
- Poista pääosoite
+ Kumoa pääosoitteeksi asettaminen
Salauksenpurkuvirhe
Julkinen nimi
Istunnon tunnus
@@ -520,7 +521,7 @@
- yksi jäsen
- %d jäsentä
- Poista huoneesta
+ Poista keskustelusta
- yksi uusi viesti
- %d uutta viestiä
@@ -628,7 +629,7 @@
Määritä käyttäjän oikeuksien taso
Poistaa käyttäjän operaattorioikeudet
Kutsuu käyttäjän nykyiseen huoneeseen
- Liittyy annettuun huoneeseen
+ Liittyy osoitteen mukaiseen huoneeseen
Poistu huoneesta
Aseta huoneen aihe
Potkaisee käyttäjän pois
@@ -646,7 +647,7 @@
\nViestien näkyvyys Matrixissa on samantapainen kuin sähköpostissa. Viestiesi unohtaminen tarkoittaa, että lähettämiäsi viestejä ei näytetä uusille tai rekisteröitymättömille käyttäjille. Ne rekisteröityneet käyttäjät, joilla viestisi jo on, pääsevät kuitenkin näkemään oman kopionsa niistä jatkossakin.