diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java index 2a816a65c9..5bb3ab8b71 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/UiHintValues.java @@ -29,6 +29,8 @@ public class UiHintValues extends SignalStoreValues { private static final String LAST_SUPPORT_VERSION_SEEN = "uihints.last_support_version_seen"; private static final String HAS_EVER_ENABLED_REMOTE_BACKUPS = "uihints.has_ever_enabled_remote_backups"; private static final String HAS_SEEN_CHAT_FOLDERS_EDUCATION_SHEET = "uihints.has_seen_chat_folders_education_sheet"; + private static final String HAS_SEEN_LINK_DEVICE_QR_EDUCATION_SHEET = "uihints.has_seen_link_device_qr_education_sheet"; + private static final String HAS_SEEN_LINK_DEVICE_AUTH_SHEET = "uihints.has_seen_link_device_auth_sheet"; UiHintValues(@NonNull KeyValueStore store) { super(store); @@ -218,4 +220,20 @@ public class UiHintValues extends SignalStoreValues { public boolean getHasSeenChatFoldersEducationSheet() { return getBoolean(HAS_SEEN_CHAT_FOLDERS_EDUCATION_SHEET, false); } + + public void markHasSeenLinkDeviceQrEducationSheet() { + putBoolean(HAS_SEEN_LINK_DEVICE_QR_EDUCATION_SHEET, true); + } + + public boolean hasSeenLinkDeviceQrEducationSheet() { + return getBoolean(HAS_SEEN_LINK_DEVICE_QR_EDUCATION_SHEET, false); + } + + public void markHasSeenLinkDeviceAuthSheet() { + putBoolean(HAS_SEEN_LINK_DEVICE_AUTH_SHEET, true); + } + + public boolean hasSeenLinkDeviceAuthSheet() { + return getBoolean(HAS_SEEN_LINK_DEVICE_AUTH_SHEET, false); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/AddLinkDeviceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/AddLinkDeviceFragment.kt index 706e8d4235..1189abf605 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/AddLinkDeviceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/AddLinkDeviceFragment.kt @@ -44,9 +44,9 @@ class AddLinkDeviceFragment : ComposeFragment() { val navController: NavController by remember { mutableStateOf(findNavController()) } val cameraPermissionState: PermissionState = rememberPermissionState(permission = Manifest.permission.CAMERA) - if (!state.seenIntroSheet) { + if (!state.seenQrEducationSheet) { navController.safeNavigate(R.id.action_addLinkDeviceFragment_to_linkDeviceIntroBottomSheet) - viewModel.markIntroSheetSeen() + viewModel.markQrEducationSheetSeen() } if (state.qrCodeState != LinkDeviceSettingsState.QrCodeState.NONE && navController.currentDestination?.id == R.id.linkDeviceIntroBottomSheet) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceEducationSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceEducationSheet.kt index 411dfeb2cd..02bda509ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceEducationSheet.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceEducationSheet.kt @@ -39,12 +39,12 @@ class LinkDeviceEducationSheet : ComposeBottomSheetDialogFragment() { } override fun onCancel(dialog: DialogInterface) { - viewModel.markEducationSheetSeen(true) + viewModel.markBioAuthEducationSheetSeen(true) super.onCancel(dialog) } fun onDismiss() { - viewModel.markEducationSheetSeen(true) + viewModel.markBioAuthEducationSheetSeen(true) dismissAllowingStateLoss() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt index e4d857f941..1cb9292a32 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceFragment.kt @@ -138,7 +138,7 @@ class LinkDeviceFragment : ComposeFragment() { Toast.makeText(context, context.getString(R.string.DeviceListActivity_network_failed), Toast.LENGTH_LONG).show() } LinkDeviceSettingsState.OneTimeEvent.LaunchQrCodeScanner -> { - navController.navigateToQrScannerIfAuthed() + navController.navigateToQrScannerIfAuthed(state.seenBioAuthEducationSheet) } LinkDeviceSettingsState.OneTimeEvent.ShowFinishedSheet -> { navController.safeNavigate(R.id.action_linkDeviceFragment_to_linkDeviceFinishedSheet) @@ -157,15 +157,6 @@ class LinkDeviceFragment : ComposeFragment() { } } - LaunchedEffect(state.seenEducationSheet) { - if (state.seenEducationSheet) { - if (!biometricAuth.authenticate(requireContext(), true) { biometricDeviceLockLauncher.launch(getString(R.string.LinkDeviceFragment__unlock_to_link)) }) { - navController.safeNavigate(R.id.action_linkDeviceFragment_to_addLinkDeviceFragment) - } - viewModel.markEducationSheetSeen(false) - } - } - Scaffolds.Settings( title = stringResource(id = R.string.preferences__linked_devices), onNavigationClick = { navController.popOrFinish() }, @@ -176,7 +167,7 @@ class LinkDeviceFragment : ComposeFragment() { state = state, modifier = Modifier.padding(contentPadding), onLearnMoreClicked = { navController.safeNavigate(R.id.action_linkDeviceFragment_to_linkDeviceLearnMoreBottomSheet) }, - onLinkNewDeviceClicked = { navController.navigateToQrScannerIfAuthed() }, + onLinkNewDeviceClicked = { navController.navigateToQrScannerIfAuthed(state.seenBioAuthEducationSheet) }, onDeviceSelectedForRemoval = { device -> viewModel.setDeviceToRemove(device) }, onDeviceRemovalConfirmed = { device -> viewModel.removeDevice(device) }, onSyncFailureRetryRequested = { viewModel.onSyncErrorRetryRequested() }, @@ -189,8 +180,10 @@ class LinkDeviceFragment : ComposeFragment() { } } - private fun NavController.navigateToQrScannerIfAuthed() { - if (biometricAuth.canAuthenticate(requireContext())) { + private fun NavController.navigateToQrScannerIfAuthed(seenEducation: Boolean) { + if (seenEducation) { + this.safeNavigate(R.id.action_linkDeviceFragment_to_addLinkDeviceFragment) + } else if (biometricAuth.canAuthenticate(requireContext())) { this.safeNavigate(R.id.action_linkDeviceFragment_to_linkDeviceEducationSheet) } else { this.safeNavigate(R.id.action_linkDeviceFragment_to_addLinkDeviceFragment) diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt index 4ae377b8c6..0e7c3adc23 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceSettingsState.kt @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.linkdevice import android.net.Uri +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkdevice.LinkDeviceRepository.LinkDeviceResult /** @@ -16,8 +17,8 @@ data class LinkDeviceSettingsState( val qrCodeState: QrCodeState = QrCodeState.NONE, val linkUri: Uri? = null, val linkDeviceResult: LinkDeviceResult = LinkDeviceResult.None, - val seenIntroSheet: Boolean = false, - val seenEducationSheet: Boolean = false, + val seenQrEducationSheet: Boolean = SignalStore.uiHints.hasSeenLinkDeviceQrEducationSheet() || SignalStore.account.hasLinkedDevices, + val seenBioAuthEducationSheet: Boolean = SignalStore.uiHints.hasSeenLinkDeviceAuthSheet() || SignalStore.account.hasLinkedDevices, val bottomSheetVisible: Boolean = false, val deviceToEdit: Device? = null ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt index d3658c9fa1..522bcc97cb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceViewModel.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.jobs.LinkedDeviceInactiveCheckJob +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.linkdevice.LinkDeviceRepository.LinkDeviceResult import org.thoughtcrime.securesms.linkdevice.LinkDeviceRepository.getPlaintextDeviceName import org.thoughtcrime.securesms.linkdevice.LinkDeviceSettingsState.DialogState @@ -99,10 +100,11 @@ class LinkDeviceViewModel : ViewModel() { } } - fun markIntroSheetSeen() { + fun markQrEducationSheetSeen() { + SignalStore.uiHints.markHasSeenLinkDeviceQrEducationSheet() _state.update { it.copy( - seenIntroSheet = true, + seenQrEducationSheet = true, showFrontCamera = null ) } @@ -192,9 +194,10 @@ class LinkDeviceViewModel : ViewModel() { } } - fun markEducationSheetSeen(seen: Boolean) { + fun markBioAuthEducationSheetSeen(seen: Boolean) { + SignalStore.uiHints.markHasSeenLinkDeviceAuthSheet() _state.update { - it.copy(seenEducationSheet = seen) + it.copy(seenBioAuthEducationSheet = seen) } }