For #7970: Updates snackbars for accessibility
parent
82c698c818
commit
1372ed5837
|
@ -75,6 +75,7 @@ class FenixSnackbar private constructor(
|
||||||
companion object {
|
companion object {
|
||||||
const val LENGTH_LONG = Snackbar.LENGTH_LONG
|
const val LENGTH_LONG = Snackbar.LENGTH_LONG
|
||||||
const val LENGTH_SHORT = Snackbar.LENGTH_SHORT
|
const val LENGTH_SHORT = Snackbar.LENGTH_SHORT
|
||||||
|
const val LENGTH_ACCESSIBLE = 15000 /* 15 seconds in ms */
|
||||||
const val LENGTH_INDEFINITE = Snackbar.LENGTH_INDEFINITE
|
const val LENGTH_INDEFINITE = Snackbar.LENGTH_INDEFINITE
|
||||||
|
|
||||||
private const val minTextSize = 12
|
private const val minTextSize = 12
|
||||||
|
@ -82,6 +83,10 @@ class FenixSnackbar private constructor(
|
||||||
private const val actionButtonIncreaseDps = 16
|
private const val actionButtonIncreaseDps = 16
|
||||||
private const val stepGranularity = 1
|
private const val stepGranularity = 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a snackbar in the given view with duration and proper normal/error styling.
|
||||||
|
* Note: Duration is overriden for users with accessibility settings enabled
|
||||||
|
*/
|
||||||
fun make(view: View, duration: Int, isError: Boolean = false): FenixSnackbar {
|
fun make(view: View, duration: Int, isError: Boolean = false): FenixSnackbar {
|
||||||
val parent = findSuitableParent(view) ?: run {
|
val parent = findSuitableParent(view) ?: run {
|
||||||
throw IllegalArgumentException(
|
throw IllegalArgumentException(
|
||||||
|
@ -92,9 +97,15 @@ class FenixSnackbar private constructor(
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
val content = inflater.inflate(R.layout.fenix_snackbar, parent, false)
|
val content = inflater.inflate(R.layout.fenix_snackbar, parent, false)
|
||||||
|
|
||||||
|
val durationOrAccessibleDuration = if (parent.context.settings().accessibilityServicesEnabled) {
|
||||||
|
LENGTH_ACCESSIBLE
|
||||||
|
} else {
|
||||||
|
duration
|
||||||
|
}
|
||||||
|
|
||||||
val callback = FenixSnackbarCallback(content)
|
val callback = FenixSnackbarCallback(content)
|
||||||
return FenixSnackbar(parent, content, callback, isError).also {
|
return FenixSnackbar(parent, content, callback, isError).also {
|
||||||
it.duration = duration
|
it.duration = durationOrAccessibleDuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,9 @@ class Settings private constructor(
|
||||||
return accessibilityManager?.isTouchExplorationEnabled ?: false
|
return accessibilityManager?.isTouchExplorationEnabled ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val accessibilityServicesEnabled: Boolean
|
||||||
|
get() { return touchExplorationIsEnabled || switchServiceIsEnabled }
|
||||||
|
|
||||||
val toolbarSettingString: String
|
val toolbarSettingString: String
|
||||||
get() = when {
|
get() = when {
|
||||||
shouldUseBottomToolbar -> appContext.getString(R.string.preference_bottom_toolbar)
|
shouldUseBottomToolbar -> appContext.getString(R.string.preference_bottom_toolbar)
|
||||||
|
|
|
@ -10,13 +10,11 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import android.app.AlertDialog
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.R
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.accessibility.AccessibilityManager
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
internal const val UNDO_DELAY = 3000L
|
internal const val UNDO_DELAY = 3000L
|
||||||
|
internal const val ACCESSIBLE_UNDO_DELAY = 15000L
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs [operation] after giving user time (see [UNDO_DELAY]) to cancel it.
|
* Runs [operation] after giving user time (see [UNDO_DELAY]) to cancel it.
|
||||||
|
@ -44,22 +42,6 @@ fun CoroutineScope.allowUndo(
|
||||||
// writing a volatile variable.
|
// writing a volatile variable.
|
||||||
val requestedUndo = AtomicBoolean(false)
|
val requestedUndo = AtomicBoolean(false)
|
||||||
|
|
||||||
fun showUndoDialog() {
|
|
||||||
val dialogBuilder = AlertDialog.Builder(view.context)
|
|
||||||
dialogBuilder.setMessage(message).setCancelable(false)
|
|
||||||
.setPositiveButton(R.string.a11y_dialog_deleted_confirm) { _, _ ->
|
|
||||||
launch {
|
|
||||||
operation.invoke()
|
|
||||||
}
|
|
||||||
}.setNegativeButton(R.string.a11y_dialog_deleted_undo) { _, _ ->
|
|
||||||
launch {
|
|
||||||
onCancel.invoke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val alert = dialogBuilder.create()
|
|
||||||
alert.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun showUndoSnackbar() {
|
fun showUndoSnackbar() {
|
||||||
val snackbar = FenixSnackbar
|
val snackbar = FenixSnackbar
|
||||||
.make(view, FenixSnackbar.LENGTH_INDEFINITE)
|
.make(view, FenixSnackbar.LENGTH_INDEFINITE)
|
||||||
|
@ -77,7 +59,13 @@ fun CoroutineScope.allowUndo(
|
||||||
// Wait a bit, and if user didn't request cancellation, proceed with
|
// Wait a bit, and if user didn't request cancellation, proceed with
|
||||||
// requested operation and hide the snackbar.
|
// requested operation and hide the snackbar.
|
||||||
launch {
|
launch {
|
||||||
delay(UNDO_DELAY)
|
val lengthToDelay = if (view.context.settings().accessibilityServicesEnabled) {
|
||||||
|
ACCESSIBLE_UNDO_DELAY
|
||||||
|
} else {
|
||||||
|
UNDO_DELAY
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(lengthToDelay)
|
||||||
|
|
||||||
if (!requestedUndo.get()) {
|
if (!requestedUndo.get()) {
|
||||||
snackbar.dismiss()
|
snackbar.dismiss()
|
||||||
|
@ -86,16 +74,5 @@ fun CoroutineScope.allowUndo(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is difficult to use our Snackbars quickly enough with
|
showUndoSnackbar()
|
||||||
// Talkback enabled, so in that case we show a dialog instead
|
|
||||||
if (touchExplorationEnabled(view)) {
|
|
||||||
showUndoDialog()
|
|
||||||
} else {
|
|
||||||
showUndoSnackbar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun touchExplorationEnabled(view: View): Boolean {
|
|
||||||
val am = view.context.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
|
|
||||||
return am.isTouchExplorationEnabled
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue