diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index f4d066945d..b0b653d08b 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -48,6 +48,8 @@
+
+
diff --git a/app/build.gradle b/app/build.gradle
index e61b370679..0f9631e7e9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -523,7 +523,6 @@ dependencies {
implementation libs.greenrobot.eventbus
implementation libs.waitingdots
implementation libs.google.zxing.android.integration
- implementation libs.time.duration.picker
implementation libs.google.zxing.core
implementation libs.google.flexbox
implementation (libs.subsampling.scale.image.view) {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/TimeDurationPickerDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/components/TimeDurationPickerDialog.kt
new file mode 100644
index 0000000000..dfd5a8aaca
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/TimeDurationPickerDialog.kt
@@ -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
+ )
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt
index 3d63d2dee5..d9d42ad02a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt
@@ -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)
}
)
}
diff --git a/app/src/main/res/layout/numeric_keyboard_view.xml b/app/src/main/res/layout/numeric_keyboard_view.xml
index 26f093fe9b..ddbd3a5536 100644
--- a/app/src/main/res/layout/numeric_keyboard_view.xml
+++ b/app/src/main/res/layout/numeric_keyboard_view.xml
@@ -15,7 +15,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__1"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_4"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_2"
app:layout_constraintStart_toStartOf="parent"
@@ -29,7 +29,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__2"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_4"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_3"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_1"
@@ -43,7 +43,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__3"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_2"
@@ -57,7 +57,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__4"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_7"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_5"
app:layout_constraintStart_toStartOf="parent"
@@ -71,7 +71,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__5"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_7"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_6"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_4"
@@ -85,7 +85,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__6"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_5"
@@ -99,7 +99,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__7"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_0"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_8"
app:layout_constraintStart_toStartOf="parent"
@@ -113,7 +113,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__8"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_0"
app:layout_constraintEnd_toStartOf="@id/numeric_keyboard_9"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_7"
@@ -127,7 +127,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__9"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toTopOf="@id/numeric_keyboard_0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/numeric_keyboard_8"
@@ -141,7 +141,7 @@
android:gravity="center"
android:text="@string/NumericKeyboardView__0"
android:textAppearance="@style/Signal.Text.TitleLarge"
- android:textColor="@color/signal_light_colorOnSurface"
+ android:textColor="@color/signal_colorOnSurface"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/numeric_keyboard_8"
app:layout_constraintStart_toStartOf="@id/numeric_keyboard_8"
@@ -159,6 +159,6 @@
app:layout_constraintStart_toStartOf="@id/numeric_keyboard_9"
app:layout_constraintTop_toBottomOf="@id/numeric_keyboard_9"
app:srcCompat="@drawable/ic_backspace_24"
- app:tint="@color/signal_light_colorOnSurface" />
+ app:tint="@color/signal_colorOnSurface" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/time_duration_picker_dialog.xml b/app/src/main/res/layout/time_duration_picker_dialog.xml
new file mode 100644
index 0000000000..c60f161308
--- /dev/null
+++ b/app/src/main/res/layout/time_duration_picker_dialog.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4290c25def..292a959429 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5605,5 +5605,15 @@
Delete username
+
+
+ h
+
+ m
+
+ Set
+
+ Minimum time before screen lock applies is 1 minute.
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index a69d9e24ac..a330419de8 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -465,13 +465,6 @@
- 0dp
-
-
diff --git a/dependencies.gradle b/dependencies.gradle
index 0cf0186baa..02f5f6fa1d 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -122,7 +122,6 @@ dependencyResolutionManagement {
alias('roundedimageview').to('com.makeramen:roundedimageview:2.1.0')
alias('materialish-progress').to('com.pnikosis:materialish-progress:1.5')
alias('waitingdots').to('pl.tajchert:waitingdots:0.1.0')
- alias('time-duration-picker').to('mobi.upod:time-duration-picker:1.1.3')
alias('subsampling-scale-image-view').to('com.davemorrissey.labs:subsampling-scale-image-view:3.10.0')
alias('android-tooltips').to('com.tomergoldst.android:tooltips:1.0.6')
alias('android-smsmms').to('com.klinkerapps:android-smsmms:4.0.1')
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 6a3efc33d6..ede531be1d 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -3364,11 +3364,6 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
-
-
-
-
-