@@ -40,7 +40,6 @@ import com.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
4040import com.bitwarden.ui.platform.components.badge.NotificationBadge
4141import com.bitwarden.ui.platform.components.button.BitwardenTextButton
4242import com.bitwarden.ui.platform.components.card.BitwardenActionCard
43- import com.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard
4443import com.bitwarden.ui.platform.components.card.actionCardExitAnimation
4544import com.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog
4645import com.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog
@@ -52,6 +51,7 @@ import com.bitwarden.ui.platform.components.model.CardStyle
5251import com.bitwarden.ui.platform.components.row.BitwardenExternalLinkRow
5352import com.bitwarden.ui.platform.components.row.BitwardenTextRow
5453import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
54+ import com.bitwarden.ui.platform.components.support.BitwardenSupportingText
5555import com.bitwarden.ui.platform.components.toggle.BitwardenSwitch
5656import com.bitwarden.ui.platform.components.util.rememberVectorPainter
5757import com.bitwarden.ui.platform.composition.LocalIntentManager
@@ -60,8 +60,6 @@ import com.bitwarden.ui.platform.resource.BitwardenDrawable
6060import com.bitwarden.ui.platform.resource.BitwardenString
6161import com.bitwarden.ui.platform.theme.BitwardenTheme
6262import com.bitwarden.ui.util.Text
63- import com.bitwarden.ui.util.asText
64- import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation
6563import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
6664import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
6765import com.x8bit.bitwarden.ui.platform.components.toggle.BitwardenUnlockWithBiometricsSwitch
@@ -72,6 +70,7 @@ import com.x8bit.bitwarden.ui.platform.manager.biometrics.BiometricsManager
7270import com.x8bit.bitwarden.ui.platform.manager.utils.startApplicationDetailsSettingsActivity
7371import com.x8bit.bitwarden.ui.platform.util.displayLabel
7472import com.x8bit.bitwarden.ui.platform.util.minutes
73+ import kotlinx.collections.immutable.ImmutableList
7574import kotlinx.collections.immutable.toImmutableList
7675import java.time.LocalTime
7776import javax.crypto.Cipher
@@ -297,15 +296,8 @@ fun AccountSecurityScreen(
297296 .padding(horizontal = 16 .dp),
298297 )
299298 Spacer (modifier = Modifier .height(height = 8 .dp))
300- SessionTimeoutPolicyRow (
301- vaultTimeoutPolicyMinutes = state.vaultTimeoutPolicyMinutes,
302- vaultTimeoutPolicyAction = state.vaultTimeoutPolicyAction,
303- modifier = Modifier
304- .fillMaxWidth()
305- .standardHorizontalMargin(),
306- )
307299 SessionTimeoutRow (
308- vaultTimeoutPolicyMinutes = state.vaultTimeoutPolicyMinutes ,
300+ vaultTimeoutPolicy = state.vaultTimeoutPolicy ,
309301 selectedVaultTimeoutType = state.vaultTimeout.type,
310302 onVaultTimeoutTypeSelect = remember(viewModel) {
311303 { viewModel.trySendAction(AccountSecurityAction .VaultTimeoutTypeSelect (it)) }
@@ -317,7 +309,7 @@ fun AccountSecurityScreen(
317309 )
318310 (state.vaultTimeout as ? VaultTimeout .Custom )?.let { customTimeout ->
319311 SessionCustomTimeoutRow (
320- vaultTimeoutPolicyMinutes = state.vaultTimeoutPolicyMinutes ,
312+ vaultTimeoutPolicy = state.vaultTimeoutPolicy ,
321313 customVaultTimeout = customTimeout,
322314 onCustomVaultTimeoutSelect = remember(viewModel) {
323315 {
@@ -331,13 +323,28 @@ fun AccountSecurityScreen(
331323 .standardHorizontalMargin(),
332324 )
333325 }
326+ state.sessionTimeoutSupportText?.let { text ->
327+ BitwardenSupportingText (
328+ text = text(),
329+ cardStyle = CardStyle .Bottom ,
330+ modifier = Modifier
331+ .fillMaxWidth()
332+ .standardHorizontalMargin(),
333+ )
334+ Spacer (modifier = Modifier .height(height = 8 .dp))
335+ }
334336 SessionTimeoutActionRow (
335- isEnabled = state.hasUnlockMechanism,
336- vaultTimeoutPolicyAction = state.vaultTimeoutPolicyAction,
337+ isEnabled = state.isSessionTimeoutActionEnabled,
337338 selectedVaultTimeoutAction = state.vaultTimeoutAction,
338339 onVaultTimeoutActionSelect = remember(viewModel) {
339340 { viewModel.trySendAction(AccountSecurityAction .VaultTimeoutActionSelect (it)) }
340341 },
342+ supportingText = state.sessionTimeoutActionSupportingText?.invoke(),
343+ cardStyle = if (state.sessionTimeoutSupportText == null ) {
344+ CardStyle .Bottom
345+ } else {
346+ CardStyle .Full
347+ },
341348 modifier = Modifier
342349 .testTag(" VaultTimeoutActionChooser" )
343350 .fillMaxWidth()
@@ -471,57 +478,16 @@ private fun AccountSecurityDialogs(
471478 }
472479}
473480
474- @Composable
475- private fun SessionTimeoutPolicyRow (
476- vaultTimeoutPolicyMinutes : Int? ,
477- vaultTimeoutPolicyAction : PolicyInformation .VaultTimeout .Action ? ,
478- modifier : Modifier = Modifier ,
479- ) {
480- // Show the policy warning if applicable.
481- if (vaultTimeoutPolicyMinutes != null || vaultTimeoutPolicyAction != null ) {
482- // Calculate the hours and minutes to show in the policy label.
483- val hours = vaultTimeoutPolicyMinutes?.floorDiv(MINUTES_PER_HOUR )
484- val minutes = vaultTimeoutPolicyMinutes?.mod(MINUTES_PER_HOUR )
485-
486- // Get the localized version of the action.
487- val action = when (vaultTimeoutPolicyAction) {
488- PolicyInformation .VaultTimeout .Action .LOCK -> BitwardenString .lock.asText()
489- PolicyInformation .VaultTimeout .Action .LOGOUT -> BitwardenString .log_out.asText()
490- null -> BitwardenString .log_out.asText()
491- }
492-
493- val policyText = if (hours == null || minutes == null ) {
494- BitwardenString .vault_timeout_action_policy_in_effect.asText(action)
495- } else if (vaultTimeoutPolicyAction == null ) {
496- BitwardenString .vault_timeout_policy_in_effect.asText(hours, minutes)
497- } else {
498- BitwardenString .vault_timeout_policy_with_action_in_effect.asText(
499- hours,
500- minutes,
501- action,
502- )
503- }
504-
505- BitwardenInfoCalloutCard (
506- text = policyText(),
507- modifier = modifier,
508- )
509- Spacer (modifier = Modifier .height(height = 8 .dp))
510- }
511- }
512-
513481@Composable
514482private fun SessionTimeoutRow (
515- vaultTimeoutPolicyMinutes : Int ? ,
483+ vaultTimeoutPolicy : VaultTimeoutPolicy ? ,
516484 selectedVaultTimeoutType : VaultTimeout .Type ,
517485 onVaultTimeoutTypeSelect : (VaultTimeout .Type ) -> Unit ,
518486 modifier : Modifier = Modifier ,
519487 resources : Resources = LocalResources .current,
520488) {
521489 var shouldShowNeverTimeoutConfirmationDialog by remember { mutableStateOf(false ) }
522- val vaultTimeoutOptions = VaultTimeout .Type
523- .entries
524- .filter { it.minutes <= (vaultTimeoutPolicyMinutes ? : Int .MAX_VALUE ) }
490+ val vaultTimeoutOptions = rememberSessionTimeoutOptions(vaultTimeoutPolicy)
525491 BitwardenMultiSelectButton (
526492 label = stringResource(id = BitwardenString .session_timeout),
527493 options = vaultTimeoutOptions.map { it.displayLabel() }.toImmutableList(),
@@ -557,10 +523,9 @@ private fun SessionTimeoutRow(
557523 }
558524}
559525
560- @Suppress(" LongMethod" )
561526@Composable
562527private fun SessionCustomTimeoutRow (
563- vaultTimeoutPolicyMinutes : Int ? ,
528+ vaultTimeoutPolicy : VaultTimeoutPolicy ? ,
564529 customVaultTimeout : VaultTimeout .Custom ,
565530 onCustomVaultTimeoutSelect : (VaultTimeout .Custom ) -> Unit ,
566531 modifier : Modifier = Modifier ,
@@ -574,7 +539,6 @@ private fun SessionCustomTimeoutRow(
574539 cardStyle = CardStyle .Middle (),
575540 modifier = modifier,
576541 ) {
577-
578542 Text (
579543 text = LocalTime
580544 .ofSecondOfDay(vaultTimeoutInMinutes * MINUTES_PER_HOUR .toLong())
@@ -592,8 +556,8 @@ private fun SessionCustomTimeoutRow(
592556 shouldShowTimePickerDialog = false
593557
594558 val totalMinutes = (hour * MINUTES_PER_HOUR ) + minute
595- if (vaultTimeoutPolicyMinutes != null &&
596- totalMinutes > vaultTimeoutPolicyMinutes
559+ if (vaultTimeoutPolicy?.minutes != null &&
560+ totalMinutes > vaultTimeoutPolicy.minutes
597561 ) {
598562 shouldShowViolatesPoliciesDialog = true
599563 } else {
@@ -615,7 +579,7 @@ private fun SessionCustomTimeoutRow(
615579 message = stringResource(id = BitwardenString .vault_timeout_to_large),
616580 onDismissRequest = {
617581 shouldShowViolatesPoliciesDialog = false
618- vaultTimeoutPolicyMinutes ?.let {
582+ vaultTimeoutPolicy?.minutes ?.let {
619583 onCustomVaultTimeoutSelect(
620584 VaultTimeout .Custom (
621585 vaultTimeoutInMinutes = it,
@@ -630,9 +594,10 @@ private fun SessionCustomTimeoutRow(
630594@Composable
631595private fun SessionTimeoutActionRow (
632596 isEnabled : Boolean ,
633- vaultTimeoutPolicyAction : PolicyInformation .VaultTimeout .Action ? ,
634597 selectedVaultTimeoutAction : VaultTimeoutAction ,
635598 onVaultTimeoutActionSelect : (VaultTimeoutAction ) -> Unit ,
599+ supportingText : String? ,
600+ cardStyle : CardStyle ,
636601 modifier : Modifier = Modifier ,
637602 resources : Resources = LocalResources .current,
638603) {
@@ -643,8 +608,6 @@ private fun SessionTimeoutActionRow(
643608 options = VaultTimeoutAction .entries.map { it.displayLabel() }.toImmutableList(),
644609 selectedOption = selectedVaultTimeoutAction.displayLabel(),
645610 onOptionSelected = { action ->
646- // The option is not selectable if there's a policy in place.
647- if (vaultTimeoutPolicyAction != null ) return @BitwardenMultiSelectButton
648611 val selectedAction = VaultTimeoutAction .entries.first {
649612 it.displayLabel.toString(resources) == action
650613 }
@@ -654,12 +617,9 @@ private fun SessionTimeoutActionRow(
654617 onVaultTimeoutActionSelect(selectedAction)
655618 }
656619 },
657- supportingText = stringResource(
658- id = BitwardenString .set_up_an_unlock_option_to_change_your_vault_timeout_action,
659- )
660- .takeUnless { isEnabled },
620+ supportingText = supportingText,
661621 textFieldTestTag = " SessionTimeoutActionStatusLabel" ,
662- cardStyle = CardStyle . Bottom ,
622+ cardStyle = cardStyle ,
663623 modifier = modifier,
664624 )
665625
@@ -760,3 +720,18 @@ private fun FingerPrintPhraseDialog(
760720 textContentColor = BitwardenTheme .colorScheme.text.primary,
761721 )
762722}
723+
724+ @Composable
725+ private fun rememberSessionTimeoutOptions (
726+ vaultTimeoutPolicy : VaultTimeoutPolicy ? ,
727+ ): ImmutableList <VaultTimeout .Type > = remember(vaultTimeoutPolicy) {
728+ VaultTimeout .Type
729+ .entries
730+ .filter { timeoutType ->
731+ vaultTimeoutPolicy
732+ ?.minutes
733+ ?.let { minutes -> timeoutType.minutes <= minutes }
734+ ? : true
735+ }
736+ .toImmutableList()
737+ }
0 commit comments