improvement: Use the same more alerting Inactive TFA badge in account view screen as in the cipher view screen

This commit is contained in:
Artem Chepurnoy 2024-02-28 12:36:39 +02:00
parent 85644efb6a
commit 45fe1dddf3
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
4 changed files with 49 additions and 52 deletions

View File

@ -103,6 +103,8 @@ import com.artemchep.keyguard.ui.theme.badgeContainer
import com.artemchep.keyguard.ui.theme.isDark import com.artemchep.keyguard.ui.theme.isDark
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@ -520,6 +522,17 @@ private fun buildItemsFlow(
copyText = copyText, copyText = copyText,
) )
} }
if (account != null && profile != null && !profile.twoFactorEnabled) {
val inactiveTfaItem = VaultViewItem.InactiveTotp(
id = "inactive_tfa",
chevron = true,
onClick = {
val intent = NavigationIntent.NavigateToBrowser(account.url)
scope.navigate(intent)
},
)
emit(inactiveTfaItem)
}
if (meta != null) { if (meta != null) {
val syncTimestamp = meta.lastSyncTimestamp val syncTimestamp = meta.lastSyncTimestamp
if (syncTimestamp != null) { if (syncTimestamp != null) {
@ -702,7 +715,7 @@ private fun buildItemsFlow(
filter = DFilter.ById( filter = DFilter.ById(
id = accountId.id, id = accountId.id,
what = DFilter.ById.What.ACCOUNT, what = DFilter.ById.What.ACCOUNT,
) ),
), ),
) )
val intent = NavigationIntent.NavigateToRoute(route) val intent = NavigationIntent.NavigateToRoute(route)
@ -741,11 +754,6 @@ private fun buildItemsFlow(
account = account, account = account,
profile = profile, profile = profile,
) )
emitTwoFactorAuth(
scope = scope,
account = account,
profile = profile,
)
val unofficialServer = profile.unofficialServer val unofficialServer = profile.unofficialServer
if (unofficialServer) { if (unofficialServer) {
val unofficialServerText = scope.translate(Res.strings.bitwarden_unofficial_server) val unofficialServerText = scope.translate(Res.strings.bitwarden_unofficial_server)
@ -905,6 +913,29 @@ private suspend fun FlowCollector<VaultViewItem>.emitEmail(
.attempt() .attempt()
.bind() .bind()
.getOrNull() .getOrNull()
val badges = kotlin.run {
val list = mutableListOf<StateFlow<VaultViewItem.Value.Badge>>()
// Account email verification badge
list += if (profile.emailVerified) {
VaultViewItem.Value.Badge(
text = scope.translate(Res.strings.email_verified),
score = 1f,
)
} else {
VaultViewItem.Value.Badge(
text = scope.translate(Res.strings.email_not_verified),
score = 0.5f,
)
}.let(::MutableStateFlow)
// Account two-factor authentication badge
if (profile.twoFactorEnabled) {
list += VaultViewItem.Value.Badge(
text = scope.translate(Res.strings.account_action_tfa_title),
score = 1f,
).let(::MutableStateFlow)
}
list
}
val emailItem = VaultViewItem.Value( val emailItem = VaultViewItem.Value(
id = id, id = id,
elevation = 1.dp, elevation = 1.dp,
@ -956,55 +987,12 @@ private suspend fun FlowCollector<VaultViewItem>.emitEmail(
) )
} }
}, },
badge = if (profile.emailVerified) { badge2 = badges,
VaultViewItem.Value.Badge(
text = scope.translate(Res.strings.email_verified),
score = 1f,
)
} else {
VaultViewItem.Value.Badge(
text = scope.translate(Res.strings.email_not_verified),
score = 0.5f,
)
},
) )
emit(emailItem) emit(emailItem)
} }
} }
private suspend fun FlowCollector<VaultViewItem>.emitTwoFactorAuth(
scope: RememberStateFlowScope,
account: DAccount,
profile: DProfile,
) {
val id = "twofa"
val twoFactorEnabled = profile.twoFactorEnabled
val item = VaultViewItem.Action(
id = id,
title = scope.translate(Res.strings.account_action_tfa_title),
text = scope.translate(Res.strings.account_action_tfa_text),
leading = {
Icon(Icons.Outlined.KeyguardTwoFa, null)
},
trailing = {
ChevronIcon()
},
badge = if (twoFactorEnabled) {
VaultViewItem.Action.Badge(
text = scope.translate(Res.strings.account_action_tfa_active_status),
score = 1f,
)
} else {
null
},
onClick = {
val intent = NavigationIntent.NavigateToBrowser(account.url)
scope.navigate(intent)
},
)
emit(item)
}
private suspend fun FlowCollector<VaultViewItem>.emitPremium( private suspend fun FlowCollector<VaultViewItem>.emitPremium(
scope: RememberStateFlowScope, scope: RememberStateFlowScope,
account: DAccount, account: DAccount,

View File

@ -15,6 +15,7 @@ import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.ui.DisabledEmphasisAlpha import com.artemchep.keyguard.ui.DisabledEmphasisAlpha
import com.artemchep.keyguard.ui.FlatDropdown import com.artemchep.keyguard.ui.FlatDropdown
import com.artemchep.keyguard.ui.FlatItemTextContent import com.artemchep.keyguard.ui.FlatItemTextContent
import com.artemchep.keyguard.ui.icons.ChevronIcon
import com.artemchep.keyguard.ui.theme.combineAlpha import com.artemchep.keyguard.ui.theme.combineAlpha
import com.artemchep.keyguard.ui.theme.onWarningContainer import com.artemchep.keyguard.ui.theme.onWarningContainer
import com.artemchep.keyguard.ui.theme.warning import com.artemchep.keyguard.ui.theme.warning
@ -53,6 +54,14 @@ fun VaultViewInactiveTotpItem(
) )
} }
}, },
trailing = if (item.chevron) {
// composable
{
ChevronIcon()
}
} else {
null
},
onClick = item.onClick, onClick = item.onClick,
) )
} }

View File

@ -246,7 +246,7 @@ sealed interface VaultViewItem {
data class InactiveTotp( data class InactiveTotp(
override val id: String, override val id: String,
val info: TwoFaServiceInfo, val chevron: Boolean,
val onClick: () -> Unit, val onClick: () -> Unit,
) : VaultViewItem { ) : VaultViewItem {
companion object companion object

View File

@ -1105,7 +1105,7 @@ private fun RememberStateFlowScope.oh(
if (isUnsecure != null) { if (isUnsecure != null) {
val model = VaultViewItem.InactiveTotp( val model = VaultViewItem.InactiveTotp(
id = "error2", id = "error2",
info = isUnsecure, chevron = false,
onClick = { onClick = {
val route = TwoFaServiceViewDialogRoute( val route = TwoFaServiceViewDialogRoute(
args = TwoFaServiceViewDialogRoute.Args(isUnsecure), args = TwoFaServiceViewDialogRoute.Args(isUnsecure),