Replace time duration picker dialog for screen lock timeout.

main
Cody Henthorne 2023-02-06 16:14:26 -05:00 zatwierdzone przez Greyson Parrelli
rodzic db65edb7df
commit 23050152de
10 zmienionych plików z 220 dodań i 48 usunięć

Wyświetl plik

@ -48,6 +48,8 @@
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
</JetCodeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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
)
}
}
}
}

Wyświetl plik

@ -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)
}
)
}

Wyświetl plik

@ -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" />
</merge>

Wyświetl plik

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<LinearLayout
android:id="@+id/duration_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/signal_colorSurfaceVariant"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingVertical="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/duration_hour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="@style/Signal.Text.HeadlineLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
tools:text="01" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/TimeDurationPickerDialog_single_letter_hour_abbreviation"
android:textAppearance="@style/Signal.Text.BodySmall"
android:textColor="@color/signal_colorOnSurfaceVariant" />
<TextView
android:id="@+id/duration_minute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:gravity="center_horizontal"
android:textAppearance="@style/Signal.Text.HeadlineLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
tools:text="01" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/TimeDurationPickerDialog_single_letter_minute_abbreviation"
android:textAppearance="@style/Signal.Text.BodySmall"
android:textColor="@color/signal_colorOnSurfaceVariant" />
</LinearLayout>
<TextView
android:id="@+id/duration_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingHorizontal="16dp"
android:text="@string/TimeDurationPickerDialog_minimum_duration_warning"
android:textColor="@color/signal_colorOnSurface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/duration_layout" />
<org.thoughtcrime.securesms.components.NumericKeyboardView
android:id="@+id/duration_keyboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/duration_header" />
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -5605,5 +5605,15 @@
<!-- Option to delete username displayed as a list item in a dialog -->
<string name="UsernameEditDialog__delete_username">Delete username</string>
<!-- Time duration picker -->
<!-- Shown in a time duration picker for selecting duration in hours and minutes, label shown after the user input value for hour, e.g., 12h -->
<string name="TimeDurationPickerDialog_single_letter_hour_abbreviation">h</string>
<!-- Shown in a time duration picker for selecting duration in hours and minutes, label shown after the user input value for minute, e.g., 24m -->
<string name="TimeDurationPickerDialog_single_letter_minute_abbreviation">m</string>
<!-- Shown in a time duration picker for selecting duration in hours and minutes, label for button that will apply the setting -->
<string name="TimeDurationPickerDialog_positive_button">Set</string>
<!-- Shown in a time duration picker for selecting duration in hours and minutes, helper text indicating minimum allowable duration -->
<string name="TimeDurationPickerDialog_minimum_duration_warning">Minimum time before screen lock applies is 1 minute.</string>
<!-- EOF -->
</resources>

Wyświetl plik

@ -465,13 +465,6 @@
<item name="android:insetBottom">0dp</item>
</style>
<style name="Widget.TimeDurationPicker.Dialog">
<item name="durationDisplayBackground">?colorControlActivated</item>
<item name="textAppearanceDisplay">@style/TextAppearance.TimeDurationPicker.Display.Large.Dark</item>
<item name="textAppearanceUnit">@style/TextAppearance.TimeDurationPicker.Unit.Large.Dark</item>
<item name="android:layoutDirection">ltr</item>
</style>
<style name="ThemeOverlay.Signal.TextInputEditText.FilledBox" parent="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
<item name="colorControlActivated">@color/signal_colorPrimary</item>
</style>

Wyświetl plik

@ -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')

Wyświetl plik

@ -3364,11 +3364,6 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="cd1610dc48c5699229502187fdc3b5c5433870d5aab159332121b1f8c1dad8c3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="mobi.upod" name="time-duration-picker" version="1.1.3">
<artifact name="time-duration-picker-1.1.3.aar">
<sha256 value="db469ce0f48dd96b892eac424ed76870e54bf00fe0a28cdcddfbe5f2a226a0e1" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="net.bytebuddy" name="byte-buddy" version="1.10.13">
<artifact name="byte-buddy-1.10.13.jar">
<sha256 value="b57f7ceb45a74b1a177f2eff9acdf9aee4d1758417c204bf5fbab867254977b2" origin="Generated by Gradle"/>