@@ -8,16 +8,21 @@ import android.widget.Toast
8
8
import androidx.compose.foundation.Image
9
9
import androidx.compose.foundation.layout.Arrangement
10
10
import androidx.compose.foundation.layout.Column
11
+ import androidx.compose.foundation.layout.Row
11
12
import androidx.compose.foundation.layout.Spacer
12
13
import androidx.compose.foundation.layout.fillMaxSize
13
14
import androidx.compose.foundation.layout.fillMaxWidth
14
15
import androidx.compose.foundation.layout.height
15
16
import androidx.compose.foundation.layout.padding
16
17
import androidx.compose.foundation.layout.size
18
+ import androidx.compose.foundation.layout.width
17
19
import androidx.compose.foundation.lazy.LazyColumn
18
20
import androidx.compose.foundation.lazy.items
19
21
import androidx.compose.foundation.rememberScrollState
22
+ import androidx.compose.foundation.shape.RoundedCornerShape
20
23
import androidx.compose.foundation.verticalScroll
24
+ import androidx.compose.material3.Card
25
+ import androidx.compose.material3.CardDefaults
21
26
import androidx.compose.material3.ExperimentalMaterial3Api
22
27
import androidx.compose.material3.FabPosition
23
28
import androidx.compose.material3.HorizontalDivider
@@ -56,7 +61,9 @@ import com.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.Ve
56
61
import com.bitwarden.authenticator.ui.platform.components.appbar.BitwardenMediumTopAppBar
57
62
import com.bitwarden.authenticator.ui.platform.components.appbar.BitwardenTopAppBar
58
63
import com.bitwarden.authenticator.ui.platform.components.appbar.action.BitwardenSearchActionItem
64
+ import com.bitwarden.authenticator.ui.platform.components.button.BitwardenFilledButton
59
65
import com.bitwarden.authenticator.ui.platform.components.button.BitwardenFilledTonalButton
66
+ import com.bitwarden.authenticator.ui.platform.components.button.BitwardenTextButton
60
67
import com.bitwarden.authenticator.ui.platform.components.card.BitwardenActionCard
61
68
import com.bitwarden.authenticator.ui.platform.components.dialog.BasicDialogState
62
69
import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenBasicDialog
@@ -139,6 +146,10 @@ fun ItemListingScreen(
139
146
)
140
147
}
141
148
149
+ ItemListingEvent .NavigateToSyncInformation -> {
150
+ intentManager.launchUri(" https://bitwarden.com/help/totp-sync" .toUri())
151
+ }
152
+
142
153
ItemListingEvent .NavigateToBitwardenSettings -> {
143
154
intentManager.startMainBitwardenAppAccountSettings()
144
155
}
@@ -230,6 +241,9 @@ fun ItemListingScreen(
230
241
viewModel.trySendAction(ItemListingAction .SyncWithBitwardenDismiss )
231
242
}
232
243
},
244
+ onSyncLearnMoreClick = remember(viewModel) {
245
+ { viewModel.trySendAction(ItemListingAction .SyncLearnMoreClick ) }
246
+ },
233
247
)
234
248
}
235
249
@@ -270,6 +284,9 @@ fun ItemListingScreen(
270
284
viewModel.trySendAction(ItemListingAction .SyncWithBitwardenClick )
271
285
}
272
286
},
287
+ onSyncLearnMoreClick = remember(viewModel) {
288
+ { viewModel.trySendAction(ItemListingAction .SyncLearnMoreClick ) }
289
+ },
273
290
onDismissSyncWithBitwardenClick = remember(viewModel) {
274
291
{
275
292
viewModel.trySendAction(ItemListingAction .SyncWithBitwardenDismiss )
@@ -339,6 +356,7 @@ private fun ItemListingContent(
339
356
onDismissDownloadBitwardenClick : () -> Unit ,
340
357
onSyncWithBitwardenClick : () -> Unit ,
341
358
onDismissSyncWithBitwardenClick : () -> Unit ,
359
+ onSyncLearnMoreClick : () -> Unit ,
342
360
) {
343
361
BitwardenScaffold (
344
362
modifier = Modifier
@@ -402,23 +420,15 @@ private fun ItemListingContent(
402
420
) {
403
421
LazyColumn {
404
422
item {
405
- when (state.actionCard) {
406
- ItemListingState .ActionCardState .DownloadBitwardenApp ->
407
- DownloadBitwardenActionCard (
408
- modifier = Modifier .padding(horizontal = 16 .dp),
409
- onDownloadBitwardenClick = onDownloadBitwardenClick,
410
- onDismissClick = onDismissDownloadBitwardenClick,
411
- )
412
-
413
- ItemListingState .ActionCardState .SyncWithBitwarden ->
414
- SyncWithBitwardenActionCard (
415
- modifier = Modifier .padding(16 .dp),
416
- onSyncWithBitwardenClick = onSyncWithBitwardenClick,
417
- onDismissClick = onDismissSyncWithBitwardenClick,
418
- )
419
-
420
- ItemListingState .ActionCardState .None -> Unit
421
- }
423
+ ActionCard (
424
+ actionCardState = state.actionCard,
425
+ onDownloadBitwardenClick = onDownloadBitwardenClick,
426
+ onDownloadBitwardenDismissClick = onDismissDownloadBitwardenClick,
427
+ onSyncWithBitwardenClick = onSyncWithBitwardenClick,
428
+ onSyncWithBitwardenDismissClick = onDismissSyncWithBitwardenClick,
429
+ onSyncLearnMoreClick = onSyncLearnMoreClick,
430
+ modifier = Modifier .padding(all = 16 .dp),
431
+ )
422
432
}
423
433
if (state.favoriteItems.isNotEmpty()) {
424
434
item {
@@ -572,6 +582,7 @@ fun EmptyItemListingContent(
572
582
onDownloadBitwardenClick : () -> Unit ,
573
583
onDismissDownloadBitwardenClick : () -> Unit ,
574
584
onSyncWithBitwardenClick : () -> Unit ,
585
+ onSyncLearnMoreClick : () -> Unit ,
575
586
onDismissSyncWithBitwardenClick : () -> Unit ,
576
587
) {
577
588
BitwardenScaffold (
@@ -635,23 +646,14 @@ fun EmptyItemListingContent(
635
646
ItemListingState .ActionCardState .SyncWithBitwarden -> Arrangement .Top
636
647
},
637
648
) {
638
- when (actionCardState) {
639
- ItemListingState .ActionCardState .DownloadBitwardenApp ->
640
- DownloadBitwardenActionCard (
641
- modifier = Modifier .padding(16 .dp),
642
- onDismissClick = onDismissDownloadBitwardenClick,
643
- onDownloadBitwardenClick = onDownloadBitwardenClick,
644
- )
645
-
646
- ItemListingState .ActionCardState .SyncWithBitwarden ->
647
- SyncWithBitwardenActionCard (
648
- modifier = Modifier .padding(16 .dp),
649
- onDismissClick = onDismissSyncWithBitwardenClick,
650
- onSyncWithBitwardenClick = onSyncWithBitwardenClick,
651
- )
652
-
653
- ItemListingState .ActionCardState .None -> Unit
654
- }
649
+ ActionCard (
650
+ actionCardState = actionCardState,
651
+ onDownloadBitwardenClick = onDownloadBitwardenClick,
652
+ onDownloadBitwardenDismissClick = onDismissDownloadBitwardenClick,
653
+ onSyncWithBitwardenClick = onSyncWithBitwardenClick,
654
+ onSyncWithBitwardenDismissClick = onDismissSyncWithBitwardenClick,
655
+ onSyncLearnMoreClick = onSyncLearnMoreClick,
656
+ )
655
657
656
658
// Add a spacer if an action card is showing:
657
659
when (actionCardState) {
@@ -735,32 +737,114 @@ private fun DownloadBitwardenActionCard(
735
737
},
736
738
)
737
739
740
+ @Suppress(" LongMethod" )
738
741
@Composable
739
742
private fun SyncWithBitwardenActionCard (
740
743
modifier : Modifier = Modifier ,
741
744
onDismissClick : () -> Unit ,
745
+ onAppSettingsClick : () -> Unit ,
746
+ onLearnMoreClick : () -> Unit ,
747
+ ) {
748
+ Card (
749
+ modifier = modifier,
750
+ shape = RoundedCornerShape (size = 16 .dp),
751
+ colors = CardDefaults .cardColors(
752
+ containerColor = MaterialTheme .colorScheme.surfaceContainer,
753
+ disabledContainerColor = MaterialTheme .colorScheme.surfaceContainer,
754
+ ),
755
+ elevation = CardDefaults .elevatedCardElevation(),
756
+ ) {
757
+ Spacer (Modifier .height(height = 4 .dp))
758
+ Row (modifier = Modifier .fillMaxWidth()) {
759
+ Spacer (Modifier .width(width = 16 .dp))
760
+ Row (
761
+ modifier = Modifier .padding(top = 12 .dp),
762
+ verticalAlignment = Alignment .CenterVertically ,
763
+ ) {
764
+ Icon (
765
+ painter = rememberVectorPainter(id = R .drawable.ic_bitwarden),
766
+ contentDescription = null ,
767
+ tint = MaterialTheme .colorScheme.primary,
768
+ modifier = Modifier .size(size = 20 .dp),
769
+ )
770
+ Spacer (Modifier .width(width = 16 .dp))
771
+ Text (
772
+ text = stringResource(id = R .string.sync_with_the_bitwarden_app),
773
+ style = MaterialTheme .typography.bodyLarge,
774
+ color = MaterialTheme .colorScheme.onSurface,
775
+ )
776
+ }
777
+ Spacer (Modifier .weight(weight = 1f ))
778
+ Spacer (Modifier .width(width = 16 .dp))
779
+ IconButton (onClick = onDismissClick) {
780
+ Icon (
781
+ painter = painterResource(id = R .drawable.ic_close),
782
+ contentDescription = stringResource(id = R .string.close),
783
+ tint = MaterialTheme .colorScheme.onSurfaceVariant,
784
+ modifier = Modifier .size(size = 24 .dp),
785
+ )
786
+ }
787
+ Spacer (Modifier .width(width = 4 .dp))
788
+ }
789
+ Text (
790
+ text = stringResource(id = R .string.sync_with_bitwarden_action_card_message),
791
+ style = MaterialTheme .typography.bodyMedium,
792
+ color = MaterialTheme .colorScheme.onSurfaceVariant,
793
+ modifier = Modifier
794
+ .padding(horizontal = 16 .dp)
795
+ .padding(start = 36 .dp, end = 48 .dp)
796
+ .fillMaxWidth(),
797
+ )
798
+ Spacer (Modifier .height(height = 16 .dp))
799
+ BitwardenFilledButton (
800
+ label = stringResource(id = R .string.take_me_to_app_settings),
801
+ onClick = onAppSettingsClick,
802
+ modifier = Modifier
803
+ .padding(horizontal = 16 .dp)
804
+ .fillMaxWidth(),
805
+ )
806
+ BitwardenTextButton (
807
+ label = stringResource(id = R .string.learn_more),
808
+ onClick = onLearnMoreClick,
809
+ modifier = Modifier
810
+ .padding(horizontal = 16 .dp)
811
+ .fillMaxWidth(),
812
+ )
813
+ Spacer (Modifier .height(height = 4 .dp))
814
+ }
815
+ }
816
+
817
+ @Composable
818
+ private fun ActionCard (
819
+ actionCardState : ItemListingState .ActionCardState ,
820
+ onDownloadBitwardenClick : () -> Unit ,
821
+ onDownloadBitwardenDismissClick : () -> Unit ,
742
822
onSyncWithBitwardenClick : () -> Unit ,
743
- ) = BitwardenActionCard (
744
- modifier = modifier,
745
- actionIcon = rememberVectorPainter(R .drawable.ic_refresh),
746
- actionText = stringResource(R .string.sync_with_bitwarden_action_card_message),
747
- callToActionText = stringResource(R .string.go_to_settings),
748
- titleText = stringResource(R .string.sync_with_the_bitwarden_app),
749
- onCardClicked = onSyncWithBitwardenClick,
750
- trailingContent = {
751
- IconButton (
752
- onClick = onDismissClick,
753
- ) {
754
- Icon (
755
- painter = painterResource(id = R .drawable.ic_close),
756
- contentDescription = stringResource(id = R .string.close),
757
- tint = MaterialTheme .colorScheme.onSurfaceVariant,
758
- modifier = Modifier
759
- .size(24 .dp),
823
+ onSyncWithBitwardenDismissClick : () -> Unit ,
824
+ onSyncLearnMoreClick : () -> Unit ,
825
+ modifier : Modifier = Modifier ,
826
+ ) {
827
+ when (actionCardState) {
828
+ ItemListingState .ActionCardState .DownloadBitwardenApp -> {
829
+ DownloadBitwardenActionCard (
830
+ modifier = modifier,
831
+ onDownloadBitwardenClick = onDownloadBitwardenClick,
832
+ onDismissClick = onDownloadBitwardenDismissClick,
760
833
)
761
834
}
762
- },
763
- )
835
+
836
+ ItemListingState .ActionCardState .SyncWithBitwarden -> {
837
+ SyncWithBitwardenActionCard (
838
+ modifier = modifier,
839
+ onAppSettingsClick = onSyncWithBitwardenClick,
840
+ onDismissClick = onSyncWithBitwardenDismissClick,
841
+ onLearnMoreClick = onSyncLearnMoreClick,
842
+ )
843
+ }
844
+
845
+ ItemListingState .ActionCardState .None -> Unit
846
+ }
847
+ }
764
848
765
849
@OptIn(ExperimentalMaterial3Api ::class )
766
850
@Composable
@@ -776,6 +860,7 @@ private fun EmptyListingContentPreview() {
776
860
onDownloadBitwardenClick = { },
777
861
onDismissDownloadBitwardenClick = { },
778
862
onSyncWithBitwardenClick = { },
863
+ onSyncLearnMoreClick = { },
779
864
onDismissSyncWithBitwardenClick = { },
780
865
)
781
866
}
0 commit comments