diff --git a/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt b/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt index f044af1ac..5eba2275e 100644 --- a/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt +++ b/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt @@ -75,6 +75,7 @@ class FenixSnackbar private constructor( companion object { const val LENGTH_LONG = Snackbar.LENGTH_LONG const val LENGTH_SHORT = Snackbar.LENGTH_SHORT + const val LENGTH_ACCESSIBLE = 15000 /* 15 seconds in ms */ const val LENGTH_INDEFINITE = Snackbar.LENGTH_INDEFINITE private const val minTextSize = 12 @@ -82,6 +83,10 @@ class FenixSnackbar private constructor( private const val actionButtonIncreaseDps = 16 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 { val parent = findSuitableParent(view) ?: run { throw IllegalArgumentException( @@ -92,9 +97,15 @@ class FenixSnackbar private constructor( val inflater = LayoutInflater.from(parent.context) 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) return FenixSnackbar(parent, content, callback, isError).also { - it.duration = duration + it.duration = durationOrAccessibleDuration } } diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index a731423d7..48a5ee50a 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -274,6 +274,9 @@ class Settings private constructor( return accessibilityManager?.isTouchExplorationEnabled ?: false } + val accessibilityServicesEnabled: Boolean + get() { return touchExplorationIsEnabled || switchServiceIsEnabled } + val toolbarSettingString: String get() = when { shouldUseBottomToolbar -> appContext.getString(R.string.preference_bottom_toolbar) diff --git a/app/src/main/java/org/mozilla/fenix/utils/Undo.kt b/app/src/main/java/org/mozilla/fenix/utils/Undo.kt index f9512be2c..97812918d 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Undo.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Undo.kt @@ -10,13 +10,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.mozilla.fenix.components.FenixSnackbar -import android.app.AlertDialog -import org.mozilla.fenix.R -import android.content.Context -import android.view.accessibility.AccessibilityManager +import org.mozilla.fenix.ext.settings import java.util.concurrent.atomic.AtomicBoolean 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. @@ -44,22 +42,6 @@ fun CoroutineScope.allowUndo( // writing a volatile variable. 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() { val snackbar = FenixSnackbar .make(view, FenixSnackbar.LENGTH_INDEFINITE) @@ -77,7 +59,13 @@ fun CoroutineScope.allowUndo( // Wait a bit, and if user didn't request cancellation, proceed with // requested operation and hide the snackbar. launch { - delay(UNDO_DELAY) + val lengthToDelay = if (view.context.settings().accessibilityServicesEnabled) { + ACCESSIBLE_UNDO_DELAY + } else { + UNDO_DELAY + } + + delay(lengthToDelay) if (!requestedUndo.get()) { snackbar.dismiss() @@ -86,16 +74,5 @@ fun CoroutineScope.allowUndo( } } - // It is difficult to use our Snackbars quickly enough with - // 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 + showUndoSnackbar() }