Use user friendly error messages in login following iOS logic (#174)
* Use user friendly error messages in login following iOS logic, fix dialog colors. * Use `AlertDialogDefaults` for the default properties of dialogs * Improve Maestro tests with wrong password dialog * Add tests for error messages
This commit is contained in:
parent
f1afd67397
commit
d36ca2907c
46 changed files with 300 additions and 113 deletions
|
|
@ -48,10 +48,10 @@ fun ConfirmationDialog(
|
|||
onThirdButtonClicked: () -> Unit = {},
|
||||
onDismiss: () -> Unit = {},
|
||||
shape: Shape = AlertDialogDefaults.shape,
|
||||
containerColor: Color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
iconContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
titleContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
containerColor: Color = AlertDialogDefaults.containerColor,
|
||||
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
|
||||
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
|
||||
textContentColor: Color = AlertDialogDefaults.textContentColor,
|
||||
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
|
||||
) {
|
||||
AlertDialog(
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
package io.element.android.libraries.designsystem.components.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.AlertDialogDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -31,10 +27,8 @@ import androidx.compose.ui.graphics.Shape
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
|
|
@ -46,10 +40,10 @@ fun ErrorDialog(
|
|||
submitText: String = stringResource(id = StringR.string.ok),
|
||||
onDismiss: () -> Unit = {},
|
||||
shape: Shape = AlertDialogDefaults.shape,
|
||||
containerColor: Color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
iconContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
titleContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
containerColor: Color = AlertDialogDefaults.containerColor,
|
||||
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
|
||||
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
|
||||
textContentColor: Color = AlertDialogDefaults.textContentColor,
|
||||
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
|
||||
) {
|
||||
AlertDialog(
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ val materialColorSchemeLight = lightColorScheme(
|
|||
surface = Color.White,
|
||||
onSurface = Color.Black,
|
||||
surfaceVariant = Gray_25,
|
||||
onSurfaceVariant = Gray_150,
|
||||
onSurfaceVariant = Gray_200,
|
||||
// TODO surfaceTint = primary,
|
||||
// TODO inverseSurface = ColorLightTokens.InverseSurface,
|
||||
// TODO inverseOnSurface = ColorLightTokens.InverseOnSurface,
|
||||
|
|
|
|||
|
|
@ -41,4 +41,7 @@ dependencies {
|
|||
implementation(libs.serialization.json)
|
||||
api(projects.libraries.sessionStorage.api)
|
||||
implementation(libs.coroutines.core)
|
||||
|
||||
testImplementation(libs.test.junit)
|
||||
testImplementation(libs.test.truth)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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 io.element.android.libraries.matrix.api.auth
|
||||
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationException
|
||||
|
||||
enum class AuthErrorCode(val value: String) {
|
||||
UNKNOWN("M_UNKNOWN"),
|
||||
USER_DEACTIVATED("M_USER_DEACTIVATED"),
|
||||
FORBIDDEN("M_FORBIDDEN")
|
||||
}
|
||||
|
||||
// This is taken from the iOS version. It seems like currently there's no better way to extract error codes
|
||||
val AuthenticationException.errorCode: AuthErrorCode
|
||||
get() {
|
||||
val message = (this as? AuthenticationException.Generic)?.message ?: return AuthErrorCode.UNKNOWN
|
||||
return enumValues<AuthErrorCode>()
|
||||
.firstOrNull { message.contains(it.value) }
|
||||
?: AuthErrorCode.UNKNOWN
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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 io.element.android.libraries.matrix.api.auth
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationException
|
||||
|
||||
class AuthErrorCodeTests {
|
||||
|
||||
@Test
|
||||
fun `errorCode finds UNKNOWN code`() {
|
||||
val error = AuthenticationException.Generic("M_UNKNOWN")
|
||||
assertThat(error.errorCode).isEqualTo(AuthErrorCode.UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `errorCode finds USER_DEACTIVATED code`() {
|
||||
val error = AuthenticationException.Generic("M_USER_DEACTIVATED")
|
||||
assertThat(error.errorCode).isEqualTo(AuthErrorCode.USER_DEACTIVATED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `errorCode finds FORBIDDEN code`() {
|
||||
val error = AuthenticationException.Generic("M_FORBIDDEN")
|
||||
assertThat(error.errorCode).isEqualTo(AuthErrorCode.FORBIDDEN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `errorCode cannot find code so it returns UNKNOWN`() {
|
||||
val error = AuthenticationException.Generic("Some other error")
|
||||
assertThat(error.errorCode).isEqualTo(AuthErrorCode.UNKNOWN)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue