Refine social auth UI and simplify manage auth state.

Extract Google sign-in into a dedicated manager with explicit cancel handling, update shared social button variants, and switch manage UI state from enum modes to a direct authorization flag.

Made-with: Cursor
This commit is contained in:
2026-03-02 03:16:46 +01:00
parent 28ad63fb4a
commit 8bf076697e
9 changed files with 257 additions and 182 deletions

View File

@@ -9,9 +9,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -54,7 +53,7 @@ enum class AirMQButtonStyle {
}
private val LegacyButtonShape = RoundedCornerShape(18.dp)
private val LegacyButtonHeight = 48.dp
private val LegacyButtonHeight = 36.dp
private val LegacyDisabledContainer = Color(0xFFE0E0E0)
private val LegacyDisabledContent = Color(0x61000000)
@@ -99,6 +98,69 @@ fun AirMQButton(
}
}
@Composable
fun AirMQSocialButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
leadingIconRes: Int? = null,
iconTint: Color = Color.Unspecified,
containerColor: Color = Color.White,
contentColor: Color = Color(0xFF202124)
) {
Button(
onClick = onClick,
enabled = enabled,
shape = LegacyButtonShape,
modifier = modifier.height(LegacyButtonHeight),
colors = ButtonDefaults.buttonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = LegacyDisabledContainer,
disabledContentColor = LegacyDisabledContent
)
) {
AirMQButtonLabel(
text = text,
leadingIconRes = leadingIconRes,
iconTint = if (enabled) iconTint else LegacyDisabledContent,
textColor = if (enabled) contentColor else LegacyDisabledContent
)
}
}
@Composable
fun AirMQOutlinedLightButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
leadingIconRes: Int? = null
) {
OutlinedButton(
onClick = onClick,
enabled = enabled,
shape = LegacyButtonShape,
border = BorderStroke(
width = 1.dp,
color = if (enabled) Color.White.copy(alpha = 0.55f) else LegacyDisabledContent
),
modifier = modifier.height(LegacyButtonHeight),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.White,
disabledContentColor = LegacyDisabledContent
)
) {
AirMQButtonLabel(
text = text,
leadingIconRes = leadingIconRes,
iconTint = if (enabled) Color.White else LegacyDisabledContent,
textColor = if (enabled) Color.White else LegacyDisabledContent
)
}
}
@Composable
fun AirMQContainedButton(
text: String,
@@ -111,7 +173,7 @@ fun AirMQContainedButton(
onClick = onClick,
enabled = enabled,
shape = LegacyButtonShape,
modifier = modifier.heightIn(min = LegacyButtonHeight),
modifier = modifier.height(LegacyButtonHeight),
colors = ButtonDefaults.buttonColors(
containerColor = LegacyButtonContained,
contentColor = LegacyButtonOnContained,
@@ -143,7 +205,7 @@ fun AirMQOutlinedButton(
width = 1.dp,
color = if (enabled) LegacyOutlineLight else LegacyDisabledContent
),
modifier = modifier.heightIn(min = LegacyButtonHeight),
modifier = modifier.height(LegacyButtonHeight),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = LegacyButtonOnOutlined,
disabledContentColor = LegacyDisabledContent
@@ -169,7 +231,7 @@ fun AirMQTextButton(
onClick = onClick,
enabled = enabled,
shape = LegacyButtonShape,
modifier = modifier.heightIn(min = LegacyButtonHeight),
modifier = modifier.height(LegacyButtonHeight),
colors = ButtonDefaults.textButtonColors(
contentColor = LegacyButtonOnText,
disabledContentColor = LegacyDisabledContent
@@ -205,7 +267,7 @@ fun AirMQGradientButton(
shape = LegacyButtonShape,
interactionSource = interactionSource,
modifier = modifier
.heightIn(min = LegacyButtonHeight)
.height(LegacyButtonHeight)
.clip(LegacyButtonShape),
contentPadding = PaddingValues(0.dp),
colors = ButtonDefaults.buttonColors(
@@ -218,7 +280,7 @@ fun AirMQGradientButton(
Box(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = LegacyButtonHeight)
.height(LegacyButtonHeight)
.clip(LegacyButtonShape)
.background(
brush = Brush.horizontalGradient(
@@ -330,3 +392,71 @@ private fun AirMQButtonsPreviewGradientWithIcon() {
}
}
}
@Preview(name = "Buttons - Social", showBackground = true)
@Composable
private fun AirMQButtonsPreviewSocial() {
AirMQTheme {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
AirMQSocialButton(
text = "Sign in with Google",
leadingIconRes = R.drawable.ic_google,
iconTint = Color.Unspecified,
containerColor = Color.White,
contentColor = Color(0xFF202124),
onClick = {},
modifier = Modifier.fillMaxWidth()
)
AirMQSocialButton(
text = "Sign in with Facebook",
leadingIconRes = R.drawable.ic_facebook,
iconTint = Color.White,
containerColor = Color(0xFF3B5998),
contentColor = Color.White,
onClick = {},
modifier = Modifier.fillMaxWidth()
)
AirMQOutlinedLightButton(
text = "Continue anonymously",
onClick = {},
modifier = Modifier.fillMaxWidth()
)
}
}
}
@Preview(name = "Buttons - Social Icon Comparison", showBackground = true)
@Composable
private fun AirMQButtonsPreviewSocialIconComparison() {
AirMQTheme {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
AirMQSocialButton(
text = "Sign in with Google",
leadingIconRes = R.drawable.ic_google,
iconTint = Color.Unspecified,
containerColor = Color.White,
contentColor = Color(0xFF202124),
onClick = {},
modifier = Modifier.fillMaxWidth()
)
AirMQSocialButton(
text = "Sign in with Google",
leadingIconRes = null,
containerColor = Color.White,
contentColor = Color(0xFF202124),
onClick = {},
modifier = Modifier.fillMaxWidth()
)
}
}
}

View File

@@ -19,10 +19,6 @@ fun DashboardScreen(
title = stringResource(id = R.string.title_dashboard),
subtitle = stringResource(id = R.string.dashboard_subtitle),
actions = listOf(
ScreenAction(stringResource(id = R.string.dashboard_open_map), onOpenMap),
ScreenAction(stringResource(id = R.string.dashboard_open_manage), onOpenManage),
ScreenAction(stringResource(id = R.string.dashboard_open_city), onOpenCity),
ScreenAction(stringResource(id = R.string.dashboard_open_device), onOpenDevice),
ScreenAction(stringResource(id = R.string.dashboard_open_news), onOpenNews),
ScreenAction(stringResource(id = R.string.manage_open_widget_constructor), onOpenWidgetConstructor)
)

View File

@@ -0,0 +1,82 @@
package org.db3.airmq.features.login
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.util.Log
import androidx.credentials.CredentialManager
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.exceptions.GetCredentialCancellationException
import androidx.credentials.exceptions.GetCredentialException
import androidx.credentials.exceptions.GetCredentialInterruptedException
import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
import androidx.credentials.exceptions.NoCredentialException
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
import org.db3.airmq.R
sealed interface GoogleSignInResult {
data class Success(val idToken: String) : GoogleSignInResult
data object Cancelled : GoogleSignInResult
data class Error(val message: String) : GoogleSignInResult
}
private const val GOOGLE_SIGN_IN_TAG = "GoogleSignIn"
suspend fun launchGoogleSignIn(context: Context): GoogleSignInResult {
return try {
val activity = context.findActivity()
val request = GetCredentialRequest.Builder()
.addCredentialOption(
GetGoogleIdOption.Builder()
.setServerClientId(context.getString(R.string.default_web_client_id))
.setFilterByAuthorizedAccounts(false)
.build()
)
.build()
val response = CredentialManager.create(context).getCredential(
context = activity,
request = request
)
val credential = response.credential
if (credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
) {
GoogleSignInResult.Success(GoogleIdTokenCredential.createFrom(credential.data).idToken)
} else {
GoogleSignInResult.Error("Unsupported credential type for Google sign-in.")
}
} catch (error: GetCredentialCancellationException) {
logGoogleSignInError(error)
GoogleSignInResult.Cancelled
} catch (error: GetCredentialException) {
logGoogleSignInError(error)
GoogleSignInResult.Error(context.getString(R.string.toast_oauth_failed))
} catch (error: GoogleIdTokenParsingException) {
Log.e(GOOGLE_SIGN_IN_TAG, "Google ID token parsing failed", error)
GoogleSignInResult.Error(context.getString(R.string.toast_oauth_failed))
} catch (error: Throwable) {
GoogleSignInResult.Error(error.message ?: context.getString(R.string.toast_oauth_failed))
}
}
private fun logGoogleSignInError(exception: GetCredentialException) {
val message = when (exception) {
is GetCredentialCancellationException -> "Google sign-in cancelled by user"
is NoCredentialException -> "No Google credential available on device"
is GetCredentialProviderConfigurationException -> "Credential provider is not configured correctly"
is GetCredentialInterruptedException -> "Credential flow interrupted; try again"
else -> "CredentialManager returned an unknown sign-in error"
}
Log.e(GOOGLE_SIGN_IN_TAG, message, exception)
}
private tailrec fun Context.findActivity(): Activity {
return when (this) {
is Activity -> this
is ContextWrapper -> baseContext.findActivity()
else -> error("Unable to find Activity context for Google sign-in.")
}
}

View File

@@ -1,21 +1,8 @@
package org.db3.airmq.features.login
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.util.Log
import android.widget.Toast
import androidx.credentials.CredentialManager
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.exceptions.GetCredentialCancellationException
import androidx.credentials.exceptions.GetCredentialException
import androidx.credentials.exceptions.GetCredentialInterruptedException
import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
import androidx.credentials.exceptions.NoCredentialException
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -25,13 +12,9 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
@@ -57,20 +40,15 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Icon
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
import kotlinx.coroutines.flow.collectLatest
import org.db3.airmq.R
import org.db3.airmq.features.common.AirMQOutlinedLightButton
import org.db3.airmq.features.common.AirMQSocialButton
import org.db3.airmq.features.login.LoginScreenContract.Action
import org.db3.airmq.features.login.LoginScreenContract.Event
import org.db3.airmq.features.login.LoginScreenContract.State
@@ -79,7 +57,6 @@ import org.db3.airmq.ui.theme.AirMQTheme
private val LegacyLoginGradientStart = Color(0xFF449CF5)
private val LegacyLoginGradientEnd = Color(0xFF5CE4BB)
private val LegacyFacebookBlue = Color(0xFF3B5998)
private const val LOGIN_TAG = "LoginScreen"
@Composable
fun LoginScreen(
@@ -95,13 +72,11 @@ fun LoginScreen(
when (action) {
Action.OpenManage -> onLogInToManage()
Action.LaunchGoogleSignIn -> {
val result = launchGoogleSignIn(context)
result.fold(
onSuccess = { viewModel.onEvent(Event.GoogleTokenReceived(it)) },
onFailure = { error ->
viewModel.onEvent(Event.GoogleSignInFailed(error.message))
}
)
when (val result = launchGoogleSignIn(context)) {
is GoogleSignInResult.Success -> viewModel.onEvent(Event.GoogleTokenReceived(result.idToken))
GoogleSignInResult.Cancelled -> viewModel.onEvent(Event.GoogleSignInCancelled)
is GoogleSignInResult.Error -> viewModel.onEvent(Event.GoogleSignInFailed(result.message))
}
}
Action.ShowContinueAnonymousDialog -> showContinueAnonymousDialog = true
Action.OpenPrivacyPolicy -> {
@@ -230,40 +205,31 @@ private fun LoginScreenContent(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
SocialSignInButton(
AirMQSocialButton(
text = stringResource(id = R.string.button_sign_in_google),
iconRes = R.drawable.ic_google,
leadingIconRes = R.drawable.ic_google,
iconTint = Color.Unspecified,
backgroundColor = Color.White,
textColor = Color(0xFF202124),
containerColor = Color.White,
contentColor = Color(0xFF202124),
modifier = Modifier.fillMaxWidth(),
onClick = { onEvent(Event.GoogleClicked) }
)
SocialSignInButton(
AirMQSocialButton(
text = stringResource(id = R.string.button_sign_in_facebook),
iconRes = R.drawable.ic_facebook,
leadingIconRes = R.drawable.ic_facebook,
iconTint = Color.White,
backgroundColor = LegacyFacebookBlue,
textColor = Color.White,
containerColor = LegacyFacebookBlue,
contentColor = Color.White,
modifier = Modifier.fillMaxWidth(),
onClick = { onEvent(Event.FacebookClicked) }
)
OutlinedButton(
onClick = { onEvent(Event.ContinueAnonymousClicked) },
shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.White
),
border = BorderStroke(1.dp, Color.White.copy(alpha = 0.55f)),
modifier = Modifier
.fillMaxWidth()
.height(40.dp)
) {
Text(
text = stringResource(id = R.string.button_continue_anonym).uppercase(),
style = MaterialTheme.typography.labelLarge
)
}
AirMQOutlinedLightButton(
text = stringResource(id = R.string.button_continue_anonym),
modifier = Modifier.fillMaxWidth(),
onClick = { onEvent(Event.ContinueAnonymousClicked) }
)
}
Spacer(modifier = Modifier.height(24.dp))
@@ -275,45 +241,6 @@ private fun LoginScreenContent(
}
}
@Composable
private fun SocialSignInButton(
text: String,
iconRes: Int,
iconTint: Color,
backgroundColor: Color,
textColor: Color,
onClick: () -> Unit
) {
Button(
onClick = onClick,
shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(
containerColor = backgroundColor,
contentColor = textColor
),
modifier = Modifier
.fillMaxWidth()
.height(40.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxHeight()
) {
Icon(
painter = painterResource(id = iconRes),
contentDescription = null,
tint = iconTint,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.size(8.dp))
Text(
text = text.uppercase(),
style = MaterialTheme.typography.labelLarge
)
}
}
}
@Composable
private fun PrivacyAndTermsFooter(onEvent: (Event) -> Unit) {
val privacyPolicy = "Privacy Policy"
@@ -388,61 +315,6 @@ private fun PrivacyAndTermsFooter(onEvent: (Event) -> Unit) {
)
}
private suspend fun launchGoogleSignIn(context: Context): Result<String> = runCatching {
val activity = context.findActivity()
val request = GetCredentialRequest.Builder()
.addCredentialOption(
GetGoogleIdOption.Builder()
.setServerClientId(context.getString(R.string.default_web_client_id))
.setFilterByAuthorizedAccounts(false)
.build()
)
.build()
val response = CredentialManager.create(context).getCredential(
context = activity,
request = request
)
val credential = response.credential
if (credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
) {
GoogleIdTokenCredential.createFrom(credential.data).idToken
} else {
error("Unsupported credential type for Google sign-in.")
}
}.recoverCatching {
when (it) {
is GetCredentialException -> {
logGoogleSignInError(it)
throw IllegalStateException(context.getString(R.string.toast_oauth_failed), it)
}
is GoogleIdTokenParsingException -> {
Log.e(LOGIN_TAG, "Google ID token parsing failed", it)
throw IllegalStateException(context.getString(R.string.toast_oauth_failed), it)
}
else -> throw it
}
}
private fun logGoogleSignInError(exception: GetCredentialException) {
val message = when (exception) {
is GetCredentialCancellationException -> "Google sign-in cancelled by user"
is NoCredentialException -> "No Google credential available on device"
is GetCredentialProviderConfigurationException -> "Credential provider is not configured correctly"
is GetCredentialInterruptedException -> "Credential flow interrupted; try again"
else -> "CredentialManager returned an unknown sign-in error"
}
Log.e(LOGIN_TAG, message, exception)
}
private tailrec fun Context.findActivity(): Activity {
return when (this) {
is Activity -> this
is ContextWrapper -> baseContext.findActivity()
else -> error("Unable to find Activity context for Google sign-in.")
}
}
@Preview(showBackground = true)
@Composable
private fun LoginScreenPreview() {

View File

@@ -18,6 +18,7 @@ object LoginScreenContract {
sealed interface Event {
data object GoogleClicked : Event
data class GoogleTokenReceived(val idToken: String) : Event
data object GoogleSignInCancelled : Event
data class GoogleSignInFailed(val message: String? = null) : Event
data object FacebookClicked : Event
data object ContinueAnonymousClicked : Event

View File

@@ -49,6 +49,9 @@ class LoginViewModel @Inject constructor(
)
)
}
Event.GoogleSignInCancelled -> {
_uiState.value = _uiState.value.copy(isLoading = false)
}
Event.FacebookClicked -> {
_actions.tryEmit(Action.ShowMessage(appContext.getString(R.string.coming_soon)))
}

View File

@@ -47,7 +47,6 @@ import org.db3.airmq.features.manage.ManageScreenContract.Action
import org.db3.airmq.features.manage.ManageScreenContract.DeviceItem
import org.db3.airmq.features.manage.ManageScreenContract.Event
import org.db3.airmq.features.manage.ManageScreenContract.State
import org.db3.airmq.features.manage.ManageScreenContract.UserMode
import org.db3.airmq.ui.theme.AirMQTheme
import org.db3.airmq.ui.theme.LegacyNavGradientEnd
import org.db3.airmq.ui.theme.LegacyNavGradientStart
@@ -99,16 +98,16 @@ private fun ManageScreenContent(
ProfileHeader(
name = uiState.userName,
email = uiState.userEmail,
isAnonymous = uiState.userMode == UserMode.ANONYMOUS,
isAnonymous = !uiState.isAuthorized,
onSettingsClick = { onEvent(Event.SettingsClicked) }
)
when (uiState.userMode) {
UserMode.ANONYMOUS -> AnonymousContent(
when (uiState.isAuthorized) {
false -> AnonymousContent(
modifier = Modifier.weight(1f),
devicesLabel = uiState.devicesLabel,
onSignIn = { onEvent(Event.SignInClicked) }
)
UserMode.AUTHORIZED -> AuthorizedContent(
true -> AuthorizedContent(
devicesLabel = uiState.devicesLabel,
devices = uiState.devices,
onOpenSetup = { onEvent(Event.SetupClicked) },
@@ -116,7 +115,7 @@ private fun ManageScreenContent(
onOpenLocation = { onEvent(Event.DeviceLocationClicked(it)) }
)
}
if (uiState.userMode == UserMode.AUTHORIZED) {
if (uiState.isAuthorized) {
Spacer(modifier = Modifier.height(8.dp))
AirMQButton(
text = stringResource(id = R.string.manage_open_widget_constructor),
@@ -147,7 +146,7 @@ private fun ProfileHeader(
) {
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxSize()
.background(
brush = Brush.verticalGradient(
colors = listOf(LegacyNavGradientEnd, LegacyNavGradientStart)
@@ -245,7 +244,6 @@ private fun AnonymousContent(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth(0.46f)
.height(48.dp)
.padding(bottom = 16.dp)
)
}
@@ -336,7 +334,7 @@ private fun ManageScreenAnonymousPreview() {
AirMQTheme {
ManageScreenContent(
uiState = State(
userMode = UserMode.ANONYMOUS,
isAuthorized = false,
userName = "Anonymous user",
userEmail = "Your preferences are not being synced, please sign in",
devicesLabel = "Sign in to add devices"
@@ -354,7 +352,7 @@ private fun ManageScreenAuthorizedPreview() {
AirMQTheme {
ManageScreenContent(
uiState = State(
userMode = UserMode.AUTHORIZED,
isAuthorized = true,
userName = "Anton Betsun",
userEmail = "messbees@gmail.com",
devicesLabel = "My devices",

View File

@@ -1,12 +1,6 @@
package org.db3.airmq.features.manage
object ManageScreenContract {
enum class UserMode {
ANONYMOUS,
AUTHORIZED
}
data class DeviceItem(
val id: String,
val name: String,
@@ -15,7 +9,7 @@ object ManageScreenContract {
)
data class State(
val userMode: UserMode = UserMode.ANONYMOUS,
val isAuthorized: Boolean = false,
val userName: String = "",
val userEmail: String = "",
val devicesLabel: String = "",

View File

@@ -18,7 +18,6 @@ import org.db3.airmq.features.manage.ManageScreenContract.Action
import org.db3.airmq.features.manage.ManageScreenContract.DeviceItem
import org.db3.airmq.features.manage.ManageScreenContract.Event
import org.db3.airmq.features.manage.ManageScreenContract.State
import org.db3.airmq.features.manage.ManageScreenContract.UserMode
import org.db3.airmq.sdk.auth.AuthService
import org.db3.airmq.sdk.auth.model.User
@@ -62,14 +61,14 @@ class ManageViewModel @Inject constructor(
}
private fun anonymousState(): State = State(
userMode = UserMode.ANONYMOUS,
isAuthorized = false,
userName = appContext.getString(R.string.text_anonymous_user),
userEmail = appContext.getString(R.string.text_please_sign_in),
devicesLabel = appContext.getString(R.string.text_sign_in_small)
)
private fun authorizedState(user: User): State = State(
userMode = UserMode.AUTHORIZED,
isAuthorized = true,
userName = user.displayName ?: appContext.getString(R.string.text_anonymous_user),
userEmail = user.email ?: "",
devicesLabel = appContext.getString(R.string.text_your_devices),