mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-28 21:57:17 +00:00
Replace time duration picker dialog for screen lock timeout.
This commit is contained in:
committed by
Greyson Parrelli
parent
db65edb7df
commit
23050152de
@@ -0,0 +1,101 @@
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.databinding.TimeDurationPickerDialogBinding
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
/**
|
||||
* Time duration dialog for selection a duration of hours and minutes. Currently
|
||||
* designed specifically for screen lock but could easily be generalized in the future
|
||||
* if needed.
|
||||
*
|
||||
* Uses [setFragmentResult] to pass the provided duration back in milliseconds.
|
||||
*/
|
||||
class TimeDurationPickerDialog : DialogFragment(), NumericKeyboardView.Listener {
|
||||
|
||||
private var _binding: TimeDurationPickerDialogBinding? = null
|
||||
private val binding: TimeDurationPickerDialogBinding
|
||||
get() = _binding!!
|
||||
|
||||
private var duration: String = "0000"
|
||||
private var full: Boolean = false
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
_binding = TimeDurationPickerDialogBinding.inflate(layoutInflater)
|
||||
|
||||
binding.durationKeyboard.listener = this
|
||||
|
||||
setDuration(requireArguments().getLong(ARGUMENT_DURATION).milliseconds)
|
||||
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setView(binding.root)
|
||||
.setPositiveButton(R.string.TimeDurationPickerDialog_positive_button) { _, _ ->
|
||||
setFragmentResult(
|
||||
RESULT_DURATION,
|
||||
bundleOf(
|
||||
RESULT_KEY_DURATION_MILLISECONDS to getDuration().inWholeMilliseconds
|
||||
)
|
||||
)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onKeyPress(keyCode: Int) {
|
||||
if (full && keyCode != -1) {
|
||||
return
|
||||
}
|
||||
|
||||
duration = if (keyCode == -1) {
|
||||
"0" + duration.substring(0, 3)
|
||||
} else {
|
||||
duration.substring(1) + keyCode
|
||||
}
|
||||
|
||||
updateDuration()
|
||||
}
|
||||
|
||||
private fun updateDuration() {
|
||||
binding.durationHour.text = duration.substring(0, 2)
|
||||
binding.durationMinute.text = duration.substring(2)
|
||||
full = duration.toInt() > 1000
|
||||
}
|
||||
|
||||
private fun setDuration(duration: Duration) {
|
||||
val hour = duration.inWholeMinutes / 60
|
||||
val minute = duration.inWholeMinutes.mod(60)
|
||||
this.duration = String.format("%02d%02d", hour, minute)
|
||||
updateDuration()
|
||||
}
|
||||
|
||||
private fun getDuration(): Duration {
|
||||
val hours = duration.substring(0, 2).toInt()
|
||||
val minutes = duration.substring(2).toInt()
|
||||
|
||||
return hours.hours.plus(minutes.minutes)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val RESULT_DURATION = "RESULT_DURATION"
|
||||
const val RESULT_KEY_DURATION_MILLISECONDS = "RESULT_KEY_DURATION_MILLISECONDS"
|
||||
|
||||
private const val ARGUMENT_DURATION = "ARGUMENT_DURATION"
|
||||
|
||||
fun create(duration: Duration): TimeDurationPickerDialog {
|
||||
return TimeDurationPickerDialog().apply {
|
||||
arguments = bundleOf(
|
||||
ARGUMENT_DURATION to duration.inWholeMilliseconds
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,17 +23,15 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import mobi.upod.timedurationpicker.TimeDurationPicker
|
||||
import mobi.upod.timedurationpicker.TimeDurationPickerDialog
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.BiometricDeviceAuthentication
|
||||
import org.thoughtcrime.securesms.BiometricDeviceLockContract
|
||||
import org.thoughtcrime.securesms.PassphraseChangeActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.TimeDurationPickerDialog
|
||||
import org.thoughtcrime.securesms.components.settings.ClickPreference
|
||||
import org.thoughtcrime.securesms.components.settings.ClickPreferenceViewHolder
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
@@ -56,8 +54,9 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
import java.lang.Integer.max
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.max
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
private val TAG = Log.tag(PrivacySettingsFragment::class.java)
|
||||
|
||||
@@ -257,15 +256,13 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac
|
||||
clickPref(
|
||||
title = DSLSettingsText.from(R.string.preferences__inactivity_timeout_interval),
|
||||
onClick = {
|
||||
TimeDurationPickerDialog(
|
||||
context,
|
||||
{ _: TimeDurationPicker?, duration: Long ->
|
||||
val timeoutMinutes = max(TimeUnit.MILLISECONDS.toMinutes(duration).toInt(), 1)
|
||||
viewModel.setObsoletePasswordTimeout(timeoutMinutes)
|
||||
},
|
||||
0,
|
||||
TimeDurationPicker.HH_MM
|
||||
).show()
|
||||
childFragmentManager.clearFragmentResult(TimeDurationPickerDialog.RESULT_DURATION)
|
||||
childFragmentManager.clearFragmentResultListener(TimeDurationPickerDialog.RESULT_DURATION)
|
||||
childFragmentManager.setFragmentResultListener(TimeDurationPickerDialog.RESULT_DURATION, this@PrivacySettingsFragment) { _, bundle ->
|
||||
val timeout = bundle.getLong(TimeDurationPickerDialog.RESULT_KEY_DURATION_MILLISECONDS).milliseconds.inWholeMinutes.toInt()
|
||||
viewModel.setObsoletePasswordTimeout(max(timeout, 1))
|
||||
}
|
||||
TimeDurationPickerDialog.create(state.screenLockActivityTimeout.seconds).show(childFragmentManager, null)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
@@ -292,15 +289,12 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac
|
||||
summary = DSLSettingsText.from(getScreenLockInactivityTimeoutSummary(state.screenLockActivityTimeout)),
|
||||
isEnabled = isKeyguardSecure && state.screenLock,
|
||||
onClick = {
|
||||
TimeDurationPickerDialog(
|
||||
context,
|
||||
{ _: TimeDurationPicker?, duration: Long ->
|
||||
val timeoutSeconds = TimeUnit.MILLISECONDS.toSeconds(duration)
|
||||
viewModel.setScreenLockTimeout(timeoutSeconds)
|
||||
},
|
||||
0,
|
||||
TimeDurationPicker.HH_MM
|
||||
).show()
|
||||
childFragmentManager.clearFragmentResult(TimeDurationPickerDialog.RESULT_DURATION)
|
||||
childFragmentManager.clearFragmentResultListener(TimeDurationPickerDialog.RESULT_DURATION)
|
||||
childFragmentManager.setFragmentResultListener(TimeDurationPickerDialog.RESULT_DURATION, this@PrivacySettingsFragment) { _, bundle ->
|
||||
viewModel.setScreenLockTimeout(bundle.getLong(TimeDurationPickerDialog.RESULT_KEY_DURATION_MILLISECONDS).milliseconds.inWholeSeconds)
|
||||
}
|
||||
TimeDurationPickerDialog.create(state.screenLockActivityTimeout.seconds).show(childFragmentManager, null)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user