Remove BigIcon loading state.
Loading is rendered in the buttons now.
This commit is contained in:
parent
6b6ce90fcb
commit
59c175ebe0
3 changed files with 86 additions and 141 deletions
|
|
@ -21,10 +21,8 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.ProgressBarRangeInfo
|
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.focused
|
import androidx.compose.ui.semantics.focused
|
||||||
import androidx.compose.ui.semantics.progressBarRangeInfo
|
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -45,7 +43,6 @@ import io.element.android.libraries.designsystem.components.button.BackButton
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.Button
|
import io.element.android.libraries.designsystem.theme.components.Button
|
||||||
import io.element.android.libraries.designsystem.theme.components.InvisibleButton
|
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||||
|
|
@ -103,19 +100,11 @@ fun IncomingVerificationView(
|
||||||
private fun IncomingVerificationHeader(step: Step, request: VerificationRequest.Incoming) {
|
private fun IncomingVerificationHeader(step: Step, request: VerificationRequest.Incoming) {
|
||||||
val iconStyle = when (step) {
|
val iconStyle = when (step) {
|
||||||
Step.Canceled -> BigIcon.Style.AlertSolid
|
Step.Canceled -> BigIcon.Style.AlertSolid
|
||||||
is Step.Initial -> if (step.isWaiting) {
|
is Step.Initial -> when (request) {
|
||||||
BigIcon.Style.Loading
|
is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
||||||
} else {
|
is VerificationRequest.Incoming.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid())
|
||||||
when (request) {
|
|
||||||
is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
|
||||||
is VerificationRequest.Incoming.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is Step.Verifying -> if (step.isWaiting) {
|
|
||||||
BigIcon.Style.Loading
|
|
||||||
} else {
|
|
||||||
BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
|
||||||
}
|
}
|
||||||
|
is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
||||||
Step.Completed -> BigIcon.Style.SuccessSolid
|
Step.Completed -> BigIcon.Style.SuccessSolid
|
||||||
Step.Failure -> BigIcon.Style.AlertSolid
|
Step.Failure -> BigIcon.Style.AlertSolid
|
||||||
}
|
}
|
||||||
|
|
@ -159,10 +148,6 @@ private fun IncomingVerificationHeader(step: Step, request: VerificationRequest.
|
||||||
.semantics(mergeDescendants = true) {
|
.semantics(mergeDescendants = true) {
|
||||||
contentDescription = timeLimitMessage
|
contentDescription = timeLimitMessage
|
||||||
focused = true
|
focused = true
|
||||||
if (iconStyle == BigIcon.Style.Loading) {
|
|
||||||
// Same code than Modifier.progressSemantics()
|
|
||||||
progressBarRangeInfo = ProgressBarRangeInfo.Indeterminate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.focusable(),
|
.focusable(),
|
||||||
iconStyle = iconStyle,
|
iconStyle = iconStyle,
|
||||||
|
|
@ -232,43 +217,37 @@ private fun IncomingVerificationBottomMenu(
|
||||||
|
|
||||||
when (step) {
|
when (step) {
|
||||||
is Step.Initial -> {
|
is Step.Initial -> {
|
||||||
if (step.isWaiting) {
|
VerificationBottomMenu {
|
||||||
// Show nothing
|
Button(
|
||||||
} else {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
VerificationBottomMenu {
|
text = stringResource(CommonStrings.action_start_verification),
|
||||||
Button(
|
enabled = !step.isWaiting,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
showProgress = step.isWaiting,
|
||||||
text = stringResource(CommonStrings.action_start_verification),
|
onClick = { eventSink(IncomingVerificationViewEvents.StartVerification) },
|
||||||
onClick = { eventSink(IncomingVerificationViewEvents.StartVerification) },
|
)
|
||||||
)
|
TextButton(
|
||||||
TextButton(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
text = stringResource(CommonStrings.action_ignore),
|
||||||
text = stringResource(CommonStrings.action_ignore),
|
enabled = !step.isWaiting,
|
||||||
onClick = { eventSink(IncomingVerificationViewEvents.IgnoreVerification) },
|
onClick = { eventSink(IncomingVerificationViewEvents.IgnoreVerification) },
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Step.Verifying -> {
|
is Step.Verifying -> {
|
||||||
if (step.isWaiting) {
|
VerificationBottomMenu {
|
||||||
// Add invisible buttons to keep the same screen layout
|
Button(
|
||||||
VerificationBottomMenu {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
InvisibleButton()
|
text = stringResource(R.string.screen_session_verification_they_match),
|
||||||
InvisibleButton()
|
enabled = !step.isWaiting,
|
||||||
}
|
showProgress = step.isWaiting,
|
||||||
} else {
|
onClick = { eventSink(IncomingVerificationViewEvents.ConfirmVerification) },
|
||||||
VerificationBottomMenu {
|
)
|
||||||
Button(
|
TextButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(R.string.screen_session_verification_they_match),
|
text = stringResource(R.string.screen_session_verification_they_dont_match),
|
||||||
onClick = { eventSink(IncomingVerificationViewEvents.ConfirmVerification) },
|
enabled = !step.isWaiting,
|
||||||
)
|
onClick = { eventSink(IncomingVerificationViewEvents.DeclineVerification) },
|
||||||
TextButton(
|
)
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = stringResource(R.string.screen_session_verification_they_dont_match),
|
|
||||||
onClick = { eventSink(IncomingVerificationViewEvents.DeclineVerification) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Step.Canceled,
|
Step.Canceled,
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,8 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.ProgressBarRangeInfo
|
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.focused
|
import androidx.compose.ui.semantics.focused
|
||||||
import androidx.compose.ui.semantics.progressBarRangeInfo
|
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -129,20 +127,16 @@ fun OutgoingVerificationView(
|
||||||
private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest.Outgoing) {
|
private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest.Outgoing) {
|
||||||
val iconStyle = when (step) {
|
val iconStyle = when (step) {
|
||||||
Step.Loading -> error("Should not happen")
|
Step.Loading -> error("Should not happen")
|
||||||
|
Step.AwaitingOtherDeviceResponse,
|
||||||
Step.Initial -> when (request) {
|
Step.Initial -> when (request) {
|
||||||
is VerificationRequest.Outgoing.CurrentSession -> BigIcon.Style.Default(CompoundIcons.Devices())
|
is VerificationRequest.Outgoing.CurrentSession -> BigIcon.Style.Default(CompoundIcons.Devices())
|
||||||
is VerificationRequest.Outgoing.User -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
is VerificationRequest.Outgoing.User -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
||||||
}
|
}
|
||||||
Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Loading
|
|
||||||
Step.Canceled -> BigIcon.Style.AlertSolid
|
Step.Canceled -> BigIcon.Style.AlertSolid
|
||||||
Step.Ready -> BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
Step.Ready -> BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
||||||
Step.Completed -> BigIcon.Style.SuccessSolid
|
Step.Completed -> BigIcon.Style.SuccessSolid
|
||||||
is Step.Verifying -> {
|
is Step.Verifying -> {
|
||||||
if (step.state is AsyncData.Loading<Unit>) {
|
BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
||||||
BigIcon.Style.Loading
|
|
||||||
} else {
|
|
||||||
BigIcon.Style.Default(CompoundIcons.ReactionSolid())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is Step.Exit -> return
|
is Step.Exit -> return
|
||||||
}
|
}
|
||||||
|
|
@ -201,10 +195,6 @@ private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest.
|
||||||
.semantics(mergeDescendants = true) {
|
.semantics(mergeDescendants = true) {
|
||||||
contentDescription = timeLimitMessage
|
contentDescription = timeLimitMessage
|
||||||
focused = true
|
focused = true
|
||||||
if (iconStyle == BigIcon.Style.Loading) {
|
|
||||||
// Same code than Modifier.progressSemantics()
|
|
||||||
progressBarRangeInfo = ProgressBarRangeInfo.Indeterminate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.focusable(),
|
.focusable(),
|
||||||
iconStyle = iconStyle,
|
iconStyle = iconStyle,
|
||||||
|
|
@ -264,11 +254,15 @@ private fun OutgoingVerificationViewBottomMenu(
|
||||||
|
|
||||||
when (verificationViewState) {
|
when (verificationViewState) {
|
||||||
Step.Loading -> error("Should not happen")
|
Step.Loading -> error("Should not happen")
|
||||||
|
is Step.AwaitingOtherDeviceResponse,
|
||||||
is Step.Initial -> {
|
is Step.Initial -> {
|
||||||
VerificationBottomMenu {
|
VerificationBottomMenu {
|
||||||
|
val isWaiting = verificationViewState is Step.AwaitingOtherDeviceResponse
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(CommonStrings.action_start_verification),
|
text = stringResource(CommonStrings.action_start_verification),
|
||||||
|
enabled = !isWaiting,
|
||||||
|
showProgress = isWaiting,
|
||||||
onClick = { eventSink(OutgoingVerificationViewEvents.RequestVerification) },
|
onClick = { eventSink(OutgoingVerificationViewEvents.RequestVerification) },
|
||||||
)
|
)
|
||||||
InvisibleButton()
|
InvisibleButton()
|
||||||
|
|
@ -298,30 +292,23 @@ private fun OutgoingVerificationViewBottomMenu(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Step.AwaitingOtherDeviceResponse -> Unit
|
|
||||||
is Step.Verifying -> {
|
is Step.Verifying -> {
|
||||||
if (isVerifying) {
|
VerificationBottomMenu {
|
||||||
// Add invisible buttons to keep the same screen layout
|
Button(
|
||||||
VerificationBottomMenu {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
InvisibleButton()
|
text = stringResource(R.string.screen_session_verification_they_match),
|
||||||
InvisibleButton()
|
enabled = !isVerifying,
|
||||||
}
|
showProgress = isVerifying,
|
||||||
} else {
|
onClick = {
|
||||||
VerificationBottomMenu {
|
eventSink(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||||
Button(
|
},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
)
|
||||||
text = stringResource(R.string.screen_session_verification_they_match),
|
|
||||||
onClick = {
|
|
||||||
eventSink(OutgoingVerificationViewEvents.ConfirmVerification)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
TextButton(
|
TextButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(R.string.screen_session_verification_they_dont_match),
|
text = stringResource(R.string.screen_session_verification_they_dont_match),
|
||||||
onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) },
|
onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) },
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Step.Completed -> {
|
is Step.Completed -> {
|
||||||
|
|
@ -334,7 +321,7 @@ private fun OutgoingVerificationViewBottomMenu(
|
||||||
InvisibleButton()
|
InvisibleButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Step.Exit -> return
|
is Step.Exit -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
|
|
@ -82,11 +81,6 @@ object BigIcon {
|
||||||
* A success style with a tinted background.
|
* A success style with a tinted background.
|
||||||
*/
|
*/
|
||||||
data object SuccessSolid : Style
|
data object SuccessSolid : Style
|
||||||
|
|
||||||
/**
|
|
||||||
* A loading style with the default background color.
|
|
||||||
*/
|
|
||||||
data object Loading : Style
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -110,7 +104,6 @@ object BigIcon {
|
||||||
Style.Success -> Color.Transparent
|
Style.Success -> Color.Transparent
|
||||||
Style.AlertSolid -> ElementTheme.colors.bgCriticalSubtle
|
Style.AlertSolid -> ElementTheme.colors.bgCriticalSubtle
|
||||||
Style.SuccessSolid -> ElementTheme.colors.bgSuccessSubtle
|
Style.SuccessSolid -> ElementTheme.colors.bgSuccessSubtle
|
||||||
Style.Loading -> ElementTheme.colors.bgSubtleSecondary
|
|
||||||
}
|
}
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|
@ -119,52 +112,39 @@ object BigIcon {
|
||||||
.background(backgroundColor),
|
.background(backgroundColor),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
if (style is Style.Loading) {
|
val icon = when (style) {
|
||||||
CircularProgressIndicator(
|
is Style.Default -> style.vectorIcon
|
||||||
modifier = Modifier.size(27.dp),
|
Style.Alert,
|
||||||
color = ElementTheme.colors.iconSecondary,
|
Style.AlertSolid -> CompoundIcons.ErrorSolid()
|
||||||
trackColor = Color.Transparent,
|
Style.Success,
|
||||||
strokeWidth = 3.dp,
|
Style.SuccessSolid -> CompoundIcons.CheckCircleSolid()
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val icon = when (style) {
|
|
||||||
is Style.Default -> style.vectorIcon
|
|
||||||
Style.Alert,
|
|
||||||
Style.AlertSolid -> CompoundIcons.ErrorSolid()
|
|
||||||
Style.Success,
|
|
||||||
Style.SuccessSolid -> CompoundIcons.CheckCircleSolid()
|
|
||||||
Style.Loading -> error("This should never be reached")
|
|
||||||
}
|
|
||||||
val contentDescription = when (style) {
|
|
||||||
is Style.Default -> style.contentDescription
|
|
||||||
Style.Alert,
|
|
||||||
Style.AlertSolid -> stringResource(CommonStrings.common_error)
|
|
||||||
Style.Success,
|
|
||||||
Style.SuccessSolid -> stringResource(CommonStrings.common_success)
|
|
||||||
Style.Loading -> error("This should never be reached")
|
|
||||||
}
|
|
||||||
val iconTint = when (style) {
|
|
||||||
is Style.Default -> if (style.useCriticalTint) {
|
|
||||||
ElementTheme.colors.iconCriticalPrimary
|
|
||||||
} else if (style.usePrimaryTint) {
|
|
||||||
ElementTheme.colors.iconPrimary
|
|
||||||
} else {
|
|
||||||
ElementTheme.colors.iconSecondary
|
|
||||||
}
|
|
||||||
Style.Alert,
|
|
||||||
Style.AlertSolid -> ElementTheme.colors.iconCriticalPrimary
|
|
||||||
Style.Success,
|
|
||||||
Style.SuccessSolid -> ElementTheme.colors.iconSuccessPrimary
|
|
||||||
Style.Loading -> error("This should never be reached")
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier.size(32.dp),
|
|
||||||
tint = iconTint,
|
|
||||||
imageVector = icon,
|
|
||||||
contentDescription = contentDescription
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
val contentDescription = when (style) {
|
||||||
|
is Style.Default -> style.contentDescription
|
||||||
|
Style.Alert,
|
||||||
|
Style.AlertSolid -> stringResource(CommonStrings.common_error)
|
||||||
|
Style.Success,
|
||||||
|
Style.SuccessSolid -> stringResource(CommonStrings.common_success)
|
||||||
|
}
|
||||||
|
val iconTint = when (style) {
|
||||||
|
is Style.Default -> if (style.useCriticalTint) {
|
||||||
|
ElementTheme.colors.iconCriticalPrimary
|
||||||
|
} else if (style.usePrimaryTint) {
|
||||||
|
ElementTheme.colors.iconPrimary
|
||||||
|
} else {
|
||||||
|
ElementTheme.colors.iconSecondary
|
||||||
|
}
|
||||||
|
Style.Alert,
|
||||||
|
Style.AlertSolid -> ElementTheme.colors.iconCriticalPrimary
|
||||||
|
Style.Success,
|
||||||
|
Style.SuccessSolid -> ElementTheme.colors.iconSuccessPrimary
|
||||||
|
}
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = iconTint,
|
||||||
|
imageVector = icon,
|
||||||
|
contentDescription = contentDescription
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -199,6 +179,5 @@ internal class BigIconStyleProvider : PreviewParameterProvider<BigIcon.Style> {
|
||||||
BigIcon.Style.Default(Icons.Filled.CatchingPokemon, useCriticalTint = true),
|
BigIcon.Style.Default(Icons.Filled.CatchingPokemon, useCriticalTint = true),
|
||||||
BigIcon.Style.Success,
|
BigIcon.Style.Success,
|
||||||
BigIcon.Style.SuccessSolid,
|
BigIcon.Style.SuccessSolid,
|
||||||
BigIcon.Style.Loading,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue