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 @@ -6,6 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
Expand All @@ -20,6 +21,7 @@ import com.simprints.infra.config.store.models.GeneralConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration.Modality.FINGERPRINT
import com.simprints.infra.uibase.viewbinding.viewBinding
import dagger.hilt.android.AndroidEntryPoint
import com.simprints.infra.resources.R as IDR

@AndroidEntryPoint
internal class SettingsFragment : PreferenceFragmentCompat() {
Expand Down Expand Up @@ -64,20 +66,16 @@ internal class SettingsFragment : PreferenceFragmentCompat() {
SettingsPasswordDialogFragment.registerForResult(
fragmentManager = childFragmentManager,
lifecycleOwner = this,
onSuccess = {
onSuccess = { action ->
viewModel.unlockSettings()
createLanguageSelectionDialog().show()
when (action) {
ACTION_LANGUAGE -> createLanguageSelectionDialog().show()
ACTION_CONFIG_UPDATE -> updateConfiguration()
}
},
)
getLanguagePreference()?.setOnPreferenceClickListener {
val password = viewModel.settingsLocked.value?.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = password,
).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
} else {
createLanguageSelectionDialog().show()
}
showPasswordIfRequired(ACTION_LANGUAGE) { createLanguageSelectionDialog().show() }
true
}

Expand All @@ -91,12 +89,27 @@ internal class SettingsFragment : PreferenceFragmentCompat() {
true
}

getUpdateConfig()?.setOnPreferenceClickListener {
showPasswordIfRequired(ACTION_CONFIG_UPDATE) { updateConfiguration() }
true
}

getAboutPreference()?.setOnPreferenceClickListener {
findNavController().navigate(R.id.action_settingsFragment_to_aboutFragment)
true
}
}

private fun showPasswordIfRequired(action: String, cb: () -> Unit) {
val password = viewModel.settingsLocked.value?.getNullablePassword()
if (password != null) {
SettingsPasswordDialogFragment.newInstance(
passwordToMatch = password,
action = action,
).show(childFragmentManager, SettingsPasswordDialogFragment.TAG)
} else cb()
}

private fun createLanguageSelectionDialog(): AlertDialog {
val languagesOptions = viewModel.generalConfiguration.value?.languageOptions.orEmpty()
val languagesCodeToName = computeAvailableLanguageCodeAndName(languagesOptions)
Expand Down Expand Up @@ -138,6 +151,13 @@ internal class SettingsFragment : PreferenceFragmentCompat() {
activity?.overridePendingTransition(0, 0)
}

private fun updateConfiguration() {
viewModel.scheduleConfigUpdate()
Toast.makeText(
requireContext(), IDR.string.dashboard_preference_update_config_scheduled, Toast.LENGTH_SHORT
).show()
}

private fun getLanguagePreference(): Preference? =
findPreference(getString(R.string.preference_select_language_key))

Expand All @@ -147,6 +167,15 @@ internal class SettingsFragment : PreferenceFragmentCompat() {
private fun getSyncInfoPreference(): Preference? =
findPreference(getString(R.string.preference_sync_info_key))

private fun getUpdateConfig(): Preference? =
findPreference(getString(R.string.preference_update_config_key))

private fun getAboutPreference(): Preference? =
findPreference(getString(R.string.preference_app_details_key))

companion object {

private const val ACTION_LANGUAGE = "language"
private const val ACTION_CONFIG_UPDATE = "configUpdate"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import com.simprints.infra.config.store.models.SettingsPasswordConfig
import com.simprints.infra.config.sync.ConfigManager
import com.simprints.infra.logging.LoggingConstants
import com.simprints.infra.logging.Simber
import com.simprints.infra.sync.SyncOrchestrator
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
internal class SettingsViewModel @Inject constructor(
private val configManager: ConfigManager,
private val syncOrchestrator: SyncOrchestrator,
) : ViewModel() {

val generalConfiguration: LiveData<GeneralConfiguration>
Expand Down Expand Up @@ -53,4 +55,8 @@ internal class SettingsViewModel @Inject constructor(
fun unlockSettings() {
_settingsLocked.postValue(SettingsPasswordConfig.Unlocked)
}

fun scheduleConfigUpdate() {
syncOrchestrator.startDeviceSync()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ class SettingsPasswordDialogFragment : DialogFragment() {
val passwordToMatch = arguments?.getString(ARG_PASSWORD).orEmpty()
if (text?.length == passwordToMatch.length) {
if (text.toString() == passwordToMatch) {
parentFragmentManager.setFragmentResult(RESULT_KEY, bundleOf(RESULT_SUCCESS to true))
parentFragmentManager.setFragmentResult(
RESULT_KEY,
bundleOf(
RESULT_SUCCESS to true,
// Pass-through the action argument to resolve action on call side
ARG_ACTION to arguments?.getString(ARG_ACTION),
)
)
dismiss()
} else {
passwordInputField.text = null
Expand All @@ -57,27 +64,30 @@ class SettingsPasswordDialogFragment : DialogFragment() {

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

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,
title: Int = IDR.string.dashboard_password_lock_title_default,
action: String? = null,
): DialogFragment = SettingsPasswordDialogFragment().also {
it.arguments = bundleOf(
ARG_TITLE to title,
ARG_ACTION to action,
ARG_PASSWORD to passwordToMatch,
)
}

fun registerForResult(
fragmentManager: FragmentManager,
lifecycleOwner: LifecycleOwner,
onSuccess: () -> Unit,
onSuccess: (String?) -> Unit,
) {
fragmentManager.setFragmentResultListener(RESULT_KEY, lifecycleOwner) { key, result ->
if (result.getBoolean(RESULT_SUCCESS)) onSuccess()
if (result.getBoolean(RESULT_SUCCESS)) onSuccess(result.getString(ARG_ACTION))
}
}
}
Expand Down
1 change: 1 addition & 0 deletions feature/dashboard/src/main/res/values/ids.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<string name="preference_select_language_key" translatable="false">select_language_preference_key</string>
<string name="preference_select_fingers_key" translatable="false">select_fingers_preference_key</string>
<string name="preference_sync_info_key" translatable="false">sync_info_preference_key</string>
<string name="preference_update_config_key" translatable="false">preference_update_config_key</string>

<string name="preferences_app_details_key" translatable="false">app_details_key</string>
<string name="preference_app_details_key" translatable="false">app_details_preference_key</string>
Expand Down
5 changes: 5 additions & 0 deletions feature/dashboard/src/main/res/xml/preference_general.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
android:key="@string/preference_sync_info_key"
android:summary="@string/dashboard_preference_summary_sync_information"
android:title="@string/dashboard_preference_sync_information_title" />

<Preference
android:key="@string/preference_update_config_key"
android:summary="@string/dashboard_preference_summary_update_config"
android:title="@string/dashboard_preference_update_config_title" />
</PreferenceCategory>

<PreferenceCategory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import com.simprints.infra.config.store.models.DeviceConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration
import com.simprints.infra.config.store.models.SettingsPasswordConfig
import com.simprints.infra.config.sync.ConfigManager
import com.simprints.infra.sync.SyncOrchestrator
import com.simprints.testtools.common.coroutines.TestCoroutineRule
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.impl.annotations.MockK
import io.mockk.slot
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
Expand All @@ -36,6 +38,9 @@ class SettingsViewModelTest {
@MockK
private lateinit var configManager: ConfigManager

@MockK
private lateinit var syncOrchestrator: SyncOrchestrator

private lateinit var viewModel: SettingsViewModel

@Before
Expand All @@ -45,7 +50,7 @@ class SettingsViewModelTest {
coEvery { configManager.getProjectConfiguration().general } returns generalConfiguration
coEvery { configManager.getDeviceConfiguration().language } returns LANGUAGE

viewModel = SettingsViewModel(configManager)
viewModel = SettingsViewModel(configManager, syncOrchestrator)
}

@Test
Expand Down Expand Up @@ -78,6 +83,13 @@ class SettingsViewModelTest {
assertThat(viewModel.settingsLocked.value).isEqualTo(SettingsPasswordConfig.Unlocked)
}

@Test
fun `trigger device sync when called`() {
viewModel.scheduleConfigUpdate()

verify { syncOrchestrator.startDeviceSync() }
}

companion object {

private const val LANGUAGE = "fr"
Expand Down
3 changes: 3 additions & 0 deletions infra/resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,14 @@
<string name="dashboard_preference_select_modules_title">Select modules</string>
<string name="dashboard_preference_app_version_title">App Version</string>
<string name="dashboard_preference_sync_information_title">Sync Information</string>
<string name="dashboard_preference_update_config_title">Update configuration</string>
<string name="dashboard_preference_scanner_version_title">Scanner Version</string>
<string name="dashboard_preference_device_id_title">Device ID</string>
<string name="dashboard_preference_summary_settings_fingers">View the fingers that will be scanned</string>
<string name="dashboard_preference_summary_sync_information">Further details on sync</string>
<string name="dashboard_preference_summary_update_config">Refresh device and project configuration</string>
<string name="dashboard_preference_copied_to_clipboard">Copied to clipboard</string>
<string name="dashboard_preference_update_config_scheduled">Configuration update started</string>


<!-- Dashboard - Sync info -->
Expand Down