twoFa -> validation naming; fixes for preview for screens (separating view model from ui); some improvements & fixes
This commit is contained in:
@@ -8,7 +8,7 @@ interface OAuthRepository {
|
||||
login: String,
|
||||
password: String,
|
||||
forceSms: Boolean,
|
||||
twoFaCode: String?,
|
||||
validationCode: String?,
|
||||
captchaSid: String?,
|
||||
captchaKey: String?
|
||||
): AuthDirectResponse
|
||||
|
||||
@@ -16,7 +16,7 @@ class OAuthRepositoryImpl(
|
||||
login: String,
|
||||
password: String,
|
||||
forceSms: Boolean,
|
||||
twoFaCode: String?,
|
||||
validationCode: String?,
|
||||
captchaSid: String?,
|
||||
captchaKey: String?
|
||||
): AuthDirectResponse = withContext(Dispatchers.IO) {
|
||||
@@ -27,8 +27,8 @@ class OAuthRepositoryImpl(
|
||||
username = login,
|
||||
password = password,
|
||||
scope = VkConstants.Auth.SCOPE,
|
||||
twoFaForceSms = forceSms,
|
||||
twoFaCode = twoFaCode,
|
||||
validationForceSms = forceSms,
|
||||
validationCode = validationCode,
|
||||
captchaSid = captchaSid,
|
||||
captchaKey = captchaKey,
|
||||
)
|
||||
|
||||
@@ -38,8 +38,6 @@ object SettingsKeys {
|
||||
const val KEY_DEBUG_PERFORM_CRASH = "debug_perform_crash"
|
||||
const val KEY_DEBUG_SHOW_CRASH_ALERT = "debug_show_crash_alert"
|
||||
const val KEY_DEBUG_HIDE_DEBUG_LIST = "debug_hide_debug_list"
|
||||
const val KEY_SHOW_NAME_IN_BUBBLES = "debug_show_title_in_bubbles"
|
||||
const val KEY_SHOW_DATE_UNDER_BUBBLES = "debug_show_date_under_bubbles"
|
||||
const val KEY_ENABLE_ANIMATIONS_IN_MESSAGES = "debug_enable_animations_in_messages"
|
||||
|
||||
const val KEY_SHOW_DEBUG_CATEGORY = "show_debug_category"
|
||||
|
||||
@@ -20,10 +20,7 @@ import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.meloda.app.fast.datastore.isUsingAmoledBackground
|
||||
import com.meloda.app.fast.datastore.isUsingDynamicColors
|
||||
import com.meloda.app.fast.datastore.model.ThemeConfig
|
||||
import com.meloda.app.fast.datastore.selectedColorScheme
|
||||
import com.meloda.app.fast.designsystem.colorschemes.ClassicColorScheme
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
|
||||
@@ -128,10 +125,10 @@ val LocalBottomPadding = compositionLocalOf {
|
||||
@Composable
|
||||
fun AppTheme(
|
||||
predefinedColorScheme: ColorScheme? = null,
|
||||
useDarkTheme: Boolean = isUsingDarkTheme(),
|
||||
useDynamicColors: Boolean = isUsingDynamicColors(),
|
||||
selectedColorScheme: Int = selectedColorScheme(),
|
||||
useAmoledBackground: Boolean = isUsingAmoledBackground(),
|
||||
useDarkTheme: Boolean = false,
|
||||
useDynamicColors: Boolean = false,
|
||||
useAmoledBackground: Boolean = false,
|
||||
selectedColorScheme: Int = 0,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme: ColorScheme = when {
|
||||
|
||||
+131
-149
@@ -81,167 +81,166 @@ fun MaterialDialog(
|
||||
)
|
||||
}
|
||||
|
||||
AppTheme {
|
||||
if (isVisible) {
|
||||
// AlertAnimation(visible = isVisible) {
|
||||
BasicAlertDialog(
|
||||
onDismissRequest = onDismissRequest
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
val canScrollBackward by remember { derivedStateOf { scrollState.value > 0 } }
|
||||
val canScrollForward by remember { derivedStateOf { scrollState.value < scrollState.maxValue } }
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = AlertDialogDefaults.containerColor,
|
||||
shape = AlertDialogDefaults.shape,
|
||||
tonalElevation = AlertDialogDefaults.TonalElevation
|
||||
) {
|
||||
Column(modifier = Modifier.padding(bottom = 10.dp)) {
|
||||
val stringTitle = title?.getString()
|
||||
if (stringTitle != null) {
|
||||
if (isVisible) {
|
||||
// AlertAnimation(visible = isVisible) {
|
||||
BasicAlertDialog(
|
||||
onDismissRequest = onDismissRequest
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
val canScrollBackward by remember { derivedStateOf { scrollState.value > 0 } }
|
||||
val canScrollForward by remember { derivedStateOf { scrollState.value < scrollState.maxValue } }
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
color = AlertDialogDefaults.containerColor,
|
||||
shape = AlertDialogDefaults.shape,
|
||||
tonalElevation = AlertDialogDefaults.TonalElevation
|
||||
) {
|
||||
Column(modifier = Modifier.padding(bottom = 10.dp)) {
|
||||
val stringTitle = title?.getString()
|
||||
if (stringTitle != null) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
}
|
||||
|
||||
Row {
|
||||
stringTitle?.let { title ->
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineSmall
|
||||
)
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
}
|
||||
}
|
||||
|
||||
if (canScrollBackward) {
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = false)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
val stringMessage = text?.getString()
|
||||
if (stringMessage != null && stringTitle == null) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
}
|
||||
|
||||
Row {
|
||||
stringTitle?.let { title ->
|
||||
stringMessage?.let { message ->
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = title,
|
||||
style = MaterialTheme.typography.headlineSmall
|
||||
text = message,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
}
|
||||
}
|
||||
|
||||
if (canScrollBackward) {
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = false)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
if (alertItems.isNotEmpty()) {
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
AlertItems(
|
||||
selectionType = itemsSelectionType,
|
||||
items = alertItems,
|
||||
onItemClick = { index ->
|
||||
onItemClick?.invoke(index)
|
||||
|
||||
val stringMessage = text?.getString()
|
||||
if (stringMessage != null && stringTitle == null) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
}
|
||||
if (itemsSelectionType == ItemsSelectionType.None) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
val newItems =
|
||||
alertItems.mapIndexed { itemIndex, item ->
|
||||
item.copy(isSelected = itemIndex == index)
|
||||
}
|
||||
|
||||
Row {
|
||||
stringMessage?.let { message ->
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = message,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
alertItems = newItems
|
||||
}
|
||||
},
|
||||
onItemCheckedChanged = { index ->
|
||||
val newItems = alertItems.toMutableList()
|
||||
val oldItem = newItems[index]
|
||||
newItems[index] =
|
||||
oldItem.copy(isSelected = !oldItem.isSelected)
|
||||
|
||||
alertItems = newItems.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
if (alertItems.isNotEmpty()) {
|
||||
)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
} else {
|
||||
customContent?.let { content ->
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
AlertItems(
|
||||
selectionType = itemsSelectionType,
|
||||
items = alertItems,
|
||||
onItemClick = { index ->
|
||||
onItemClick?.invoke(index)
|
||||
|
||||
if (itemsSelectionType == ItemsSelectionType.None) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
val newItems =
|
||||
alertItems.mapIndexed { itemIndex, item ->
|
||||
item.copy(isSelected = itemIndex == index)
|
||||
}
|
||||
|
||||
alertItems = newItems
|
||||
}
|
||||
},
|
||||
onItemCheckedChanged = { index ->
|
||||
val newItems = alertItems.toMutableList()
|
||||
val oldItem = newItems[index]
|
||||
newItems[index] =
|
||||
oldItem.copy(isSelected = !oldItem.isSelected)
|
||||
|
||||
alertItems = newItems.toImmutableList()
|
||||
}
|
||||
)
|
||||
content.invoke(this)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
} else {
|
||||
customContent?.let { content ->
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
content.invoke(this)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canScrollForward) {
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
|
||||
Row {
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
neutralText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
neutralAction?.invoke()
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
if (canScrollForward) {
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
cancelText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
cancelAction?.invoke()
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
neutralText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
neutralAction?.invoke()
|
||||
Spacer(modifier = Modifier.width(2.dp))
|
||||
|
||||
confirmText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
confirmAction?.invoke()
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
cancelText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
cancelAction?.invoke()
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(2.dp))
|
||||
|
||||
confirmText?.getString()?.let { text ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (buttonsInvokeDismiss) {
|
||||
onDismissRequest.invoke()
|
||||
} else {
|
||||
isVisible = false
|
||||
}
|
||||
confirmAction?.invoke()
|
||||
}
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,23 +262,6 @@ fun AlertAnimation(
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AlertItemsPreview() {
|
||||
AppTheme {
|
||||
AlertItems(
|
||||
selectionType = ItemsSelectionType.None,
|
||||
items = ImmutableList(5) { index ->
|
||||
DialogItem(
|
||||
title = "Item #${index + 1}",
|
||||
isSelected = index % 2 == 0
|
||||
)
|
||||
},
|
||||
onItemClick = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AlertItems(
|
||||
selectionType: ItemsSelectionType,
|
||||
|
||||
@@ -7,9 +7,9 @@ data class AuthDirectRequest(
|
||||
val username: String,
|
||||
val password: String,
|
||||
val scope: String,
|
||||
val twoFaSupported: Boolean = true,
|
||||
val twoFaForceSms: Boolean = false,
|
||||
val twoFaCode: String? = null,
|
||||
val validationSupported: Boolean = true,
|
||||
val validationForceSms: Boolean = false,
|
||||
val validationCode: String? = null,
|
||||
val captchaSid: String? = null,
|
||||
val captchaKey: String? = null,
|
||||
val trustedHash: String? = null
|
||||
@@ -23,11 +23,11 @@ data class AuthDirectRequest(
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"scope" to scope,
|
||||
"2fa_supported" to if (twoFaSupported) "1" else "0",
|
||||
"force_sms" to if (twoFaForceSms) "1" else "0"
|
||||
"2fa_supported" to if (validationSupported) "1" else "0",
|
||||
"force_sms" to if (validationForceSms) "1" else "0"
|
||||
)
|
||||
.apply {
|
||||
twoFaCode?.let { this["code"] = it }
|
||||
validationCode?.let { this["code"] = it }
|
||||
captchaSid?.let { this["captcha_sid"] = it }
|
||||
captchaKey?.let { this["captcha_key"] = it }
|
||||
trustedHash?.let { this["trusted_hash"] = it }
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.squareup.moshi.JsonClass
|
||||
data class AuthDirectResponse(
|
||||
@Json(name = "access_token") val accessToken: String?,
|
||||
@Json(name = "user_id") val userId: Int?,
|
||||
@Json(name = "trusted_hash") val twoFaHash: String?,
|
||||
@Json(name = "trusted_hash") val validationHash: String?,
|
||||
@Json(name = "validation_sid") val validationSid: String?,
|
||||
@Json(name = "validation_type") val validationType: String?,
|
||||
@Json(name = "phone_mask") val phoneMask: String?,
|
||||
|
||||
@@ -75,7 +75,7 @@ data class InvalidCredentialsError(
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WrongTwoFaCodeError(
|
||||
data class WrongValidationCodeError(
|
||||
@Json(name = "error") override val error: String, // "invalid_request"
|
||||
@Json(name = "error_description") override val errorDescription: String,
|
||||
@Json(name = "error_type") override val errorType: String // "wrong_otp"
|
||||
@@ -86,7 +86,7 @@ data class WrongTwoFaCodeError(
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WrongTwoFaCodeFormatError(
|
||||
data class WrongValidationCodeFormatError(
|
||||
@Json(name = "error") override val error: String, // "invalid_request"
|
||||
@Json(name = "error_description") override val errorDescription: String,
|
||||
@Json(name = "error_type") override val errorType: String // "otp_format_is_incorrect"
|
||||
@@ -140,12 +140,12 @@ fun OAuthError.toDomain(): OAuthErrorDomain? = when (this) {
|
||||
OAuthErrorDomain.InvalidCredentialsError
|
||||
}
|
||||
|
||||
is WrongTwoFaCodeError -> {
|
||||
OAuthErrorDomain.WrongTwoFaCode
|
||||
is WrongValidationCodeError -> {
|
||||
OAuthErrorDomain.WrongValidationCode
|
||||
}
|
||||
|
||||
is WrongTwoFaCodeFormatError -> {
|
||||
OAuthErrorDomain.WrongTwoFaCodeFormat
|
||||
is WrongValidationCodeFormatError -> {
|
||||
OAuthErrorDomain.WrongValidationCodeFormat
|
||||
}
|
||||
|
||||
is TooManyTriesError -> {
|
||||
|
||||
@@ -25,8 +25,8 @@ sealed class OAuthErrorDomain {
|
||||
) : OAuthErrorDomain()
|
||||
|
||||
data object InvalidCredentialsError : OAuthErrorDomain()
|
||||
data object WrongTwoFaCode : OAuthErrorDomain()
|
||||
data object WrongTwoFaCodeFormat : OAuthErrorDomain()
|
||||
data object WrongValidationCode : OAuthErrorDomain()
|
||||
data object WrongValidationCodeFormat : OAuthErrorDomain()
|
||||
data object TooManyTriesError: OAuthErrorDomain()
|
||||
|
||||
data object UnknownError : OAuthErrorDomain()
|
||||
|
||||
@@ -128,12 +128,12 @@ internal class ResultCall<R : Any, E : OAuthError>(
|
||||
"invalid_request" -> {
|
||||
when (val type = baseError.errorType) {
|
||||
"wrong_otp" -> {
|
||||
moshi.adapter(WrongTwoFaCodeError::class.java)
|
||||
moshi.adapter(WrongValidationCodeError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
}
|
||||
|
||||
"otp_format_is_incorrect" -> {
|
||||
moshi.adapter(WrongTwoFaCodeFormatError::class.java)
|
||||
moshi.adapter(WrongValidationCodeFormatError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user