Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,21 @@ class LogoutSyncDeclineFragment : Fragment(R.layout.fragment_logout_sync_decline
logoutWithoutSyncCancelButton.setOnClickListener {
findNavController().popBackStack()
}
SettingsPasswordDialogFragment.registerForResult(
fragmentManager = childFragmentManager,
lifecycleOwner = this@LogoutSyncDeclineFragment,
onSuccess = { processLogoutConfirmation() }
)

logoutWithoutSyncConfirmButton.setOnClickListener {
viewModel.settingsLocked.observe(
viewLifecycleOwner,
LiveDataEventWithContentObserver { config ->
val password = config.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
title = IDR.string.dashboard_password_lock_title_logout,
passwordToMatch = password,
onSuccess = { processLogoutConfirmation() }
).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
} else {
confirmationDialogForLogout.show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,19 @@ internal class SettingsFragment : PreferenceFragmentCompat() {
}

private fun bindClickListeners() {
SettingsPasswordDialogFragment.registerForResult(
fragmentManager = childFragmentManager,
lifecycleOwner = this,
onSuccess = {
viewModel.unlockSettings()
createLanguageSelectionDialog().show()
},
)
getLanguagePreference()?.setOnPreferenceClickListener {
val password = viewModel.settingsLocked.value?.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = password,
onSuccess = {
viewModel.unlockSettings()
createLanguageSelectionDialog().show()
},
).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
} else {
createLanguageSelectionDialog().show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ internal class AboutFragment : PreferenceFragmentCompat() {
activity?.runOnUiThread {
val password = viewModel.settingsLocked.value?.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.registerForResult(
fragmentManager = childFragmentManager,
lifecycleOwner = this@AboutFragment,
onSuccess = { viewModel.processLogoutRequest() }
)
SettingsPasswordDialogFragment.newInstance(
title = IDR.string.dashboard_password_lock_title_logout,
passwordToMatch = password,
onSuccess = { viewModel.processLogoutRequest() }

).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
} else {
confirmationDialogForLogout.show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ package com.simprints.feature.dashboard.settings.password
import android.app.Dialog
import android.os.Bundle
import android.text.Editable
import androidx.annotation.StringRes
import androidx.core.os.bundleOf
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.simprints.feature.dashboard.databinding.FragmentSettingsPasswordInputBinding
import dagger.hilt.android.AndroidEntryPoint
import com.simprints.infra.resources.R as IDR

class SettingsPasswordDialogFragment(
@StringRes val title: Int = IDR.string.dashboard_password_lock_title_default,
val passwordToMatch: String,
val onSuccess: () -> Unit,
) : DialogFragment() {
@AndroidEntryPoint
class SettingsPasswordDialogFragment : DialogFragment() {

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = MaterialAlertDialogBuilder(requireContext())
.setTitle(title)
.setTitle(arguments?.getInt(ARG_TITLE) ?: IDR.string.dashboard_password_lock_title_default)
.setView(inflateInputView())
.setNegativeButton(IDR.string.dashboard_password_lock_cancel) { _, _ -> dismiss() }
.create()
Expand All @@ -40,9 +40,10 @@ class SettingsPasswordDialogFragment(
}

private fun FragmentSettingsPasswordInputBinding.checkPassword(text: Editable?) {
val passwordToMatch = arguments?.getString(ARG_PASSWORD).orEmpty()
if (text?.length == passwordToMatch.length) {
if (text.toString() == passwordToMatch) {
onSuccess()
parentFragmentManager.setFragmentResult(RESULT_KEY, bundleOf(RESULT_SUCCESS to true))
dismiss()
} else {
passwordInputField.text = null
Expand All @@ -53,5 +54,31 @@ class SettingsPasswordDialogFragment(

companion object {
const val TAG = "SettingsPasswordDialogFragment"

private const val ARG_TITLE = "titleRes"
private const val ARG_PASSWORD = "toMatch"

private const val RESULT_KEY = "$TAG-result"
private const val RESULT_SUCCESS = "success"

fun newInstance(
title: Int = IDR.string.dashboard_password_lock_title_default,
passwordToMatch: String,
): DialogFragment = SettingsPasswordDialogFragment().also {
it.arguments = bundleOf(
ARG_TITLE to title,
ARG_PASSWORD to passwordToMatch,
)
}

fun registerForResult(
fragmentManager: FragmentManager,
lifecycleOwner: LifecycleOwner,
onSuccess: () -> Unit,
) {
fragmentManager.setFragmentResultListener(RESULT_KEY, lifecycleOwner) { key, result ->
if (result.getBoolean(RESULT_SUCCESS)) onSuccess()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,16 @@ internal class ModuleSelectionFragment : Fragment(R.layout.fragment_sync_module_
viewModel.screenLocked.observe(viewLifecycleOwner) {
binding.modulesLockOverlay.isVisible = it?.locked == true
}
SettingsPasswordDialogFragment.registerForResult(
fragmentManager = childFragmentManager,
lifecycleOwner = this,
onSuccess = { viewModel.unlockScreen() }
)
binding.modulesLockOverlayClickableArea.setOnClickListener {
val password = viewModel.screenLocked.value?.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = password,
onSuccess = { viewModel.unlockScreen() }
).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
}
}
Expand Down Expand Up @@ -129,7 +133,7 @@ internal class ModuleSelectionFragment : Fragment(R.layout.fragment_sync_module_

private fun fetchData() {
viewModel.modulesList.observe(viewLifecycleOwner) {
if(hasModulesSelectedInitially == null) {
if (hasModulesSelectedInitially == null) {
hasModulesSelectedInitially = it.any(Module::isSelected)
}
modulesToSelect = it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,24 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.simprints.feature.dashboard.R
import kotlinx.coroutines.test.runTest
import org.junit.Assert.fail
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import com.google.android.material.R as MR
import com.simprints.infra.resources.R as IDR

@Ignore("launchFragment does not support fragments built with factory methods")
@RunWith(AndroidJUnit4::class)
class SettingsPasswordDialogFragmentTest {

@Test
fun `closes without success on cancel`() {
launchFragment(themeResId = MR.style.Theme_MaterialComponents) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = "1234",
onSuccess = { fail() }
//onSuccess = { fail() }
)
}
onView(withId(android.R.id.button2))
Expand All @@ -36,9 +38,9 @@ class SettingsPasswordDialogFragmentTest {
@Test
fun `shows error if incorrect password`() {
launchFragment(themeResId = MR.style.Theme_MaterialComponents) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = "1234",
onSuccess = { fail() }
// onSuccess = { fail() }
)
}

Expand All @@ -57,9 +59,9 @@ class SettingsPasswordDialogFragmentTest {
@Test
fun `resets error on new password attempt`() {
launchFragment(themeResId = MR.style.Theme_MaterialComponents) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = "1234",
onSuccess = { fail() }
// onSuccess = { fail() }
)
}

Expand All @@ -85,9 +87,9 @@ class SettingsPasswordDialogFragmentTest {
fun `triggers callback when password matches`() = runTest {
suspendCoroutine { cont ->
launchFragment(themeResId = MR.style.Theme_MaterialComponents) {
SettingsPasswordDialogFragment(
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = "1234",
onSuccess = { cont.resume(Unit) }
// onSuccess = { cont.resume(Unit) }
)
}

Expand Down