mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
Give ConfirmSwiper an accessible-navigation button fallback (#3464)
This commit is contained in:
@@ -218,6 +218,7 @@ class _BridgeConfirmSheetState extends State<BridgeConfirmSheet> {
|
|||||||
bridgeViewModel.executeBridge();
|
bridgeViewModel.executeBridge();
|
||||||
},
|
},
|
||||||
swiperText: S.of(context).swipe_to_bridge,
|
swiperText: S.of(context).swipe_to_bridge,
|
||||||
|
accessibleNavigationModeButtonText: S.of(context).confirm,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ConfirmSwiper extends StatefulWidget {
|
class ConfirmSwiper extends StatefulWidget {
|
||||||
final VoidCallback onConfirmed;
|
final VoidCallback onConfirmed;
|
||||||
final String swiperText;
|
final String swiperText;
|
||||||
|
|
||||||
const ConfirmSwiper({super.key, required this.onConfirmed, required this.swiperText});
|
/// Label of the plain button rendered instead of the swiper when the platform
|
||||||
|
/// reports accessible navigation (VoiceOver / TalkBack), which intercepts the
|
||||||
|
/// horizontal drag the swiper depends on. Falls back to [swiperText].
|
||||||
|
final String? accessibleNavigationModeButtonText;
|
||||||
|
|
||||||
|
const ConfirmSwiper({
|
||||||
|
super.key,
|
||||||
|
required this.onConfirmed,
|
||||||
|
required this.swiperText,
|
||||||
|
this.accessibleNavigationModeButtonText,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ConfirmSwiper> createState() => _ConfirmSwiperState();
|
State<ConfirmSwiper> createState() => _ConfirmSwiperState();
|
||||||
@@ -30,6 +41,15 @@ class _ConfirmSwiperState extends State<ConfirmSwiper> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (MediaQuery.of(context).accessibleNavigation) {
|
||||||
|
return NewPrimaryButton(
|
||||||
|
onPressed: widget.onConfirmed,
|
||||||
|
text: widget.accessibleNavigationModeButtonText ?? widget.swiperText,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final radius = (pillSize + pillHorizontalPadding * 2) / 2;
|
final radius = (pillSize + pillHorizontalPadding * 2) / 2;
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
@@ -41,7 +61,7 @@ class _ConfirmSwiperState extends State<ConfirmSwiper> {
|
|||||||
final maxDrag = areaWidth - pillSize - pillHorizontalPadding;
|
final maxDrag = areaWidth - pillSize - pillHorizontalPadding;
|
||||||
final triggerAt = maxDrag - _triggerThreshold;
|
final triggerAt = maxDrag - _triggerThreshold;
|
||||||
|
|
||||||
return GestureDetector(
|
final swiper = GestureDetector(
|
||||||
onHorizontalDragUpdate: (d) {
|
onHorizontalDragUpdate: (d) {
|
||||||
setState(() {
|
setState(() {
|
||||||
drag = max(pillHorizontalPadding, min(maxDrag, drag + d.delta.dx));
|
drag = max(pillHorizontalPadding, min(maxDrag, drag + d.delta.dx));
|
||||||
@@ -98,6 +118,17 @@ class _ConfirmSwiperState extends State<ConfirmSwiper> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// A single accessibility node for the whole control: the flowing label and
|
||||||
|
// the arrow knob are decorative and must not become separate stops. No
|
||||||
|
// semantics action is exposed here; a screen reader gets the button
|
||||||
|
// variant above instead.
|
||||||
|
return Semantics(
|
||||||
|
container: true,
|
||||||
|
excludeSemantics: true,
|
||||||
|
label: widget.swiperText,
|
||||||
|
child: swiper,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ class SendConfirmBottomWidget extends StatelessWidget {
|
|||||||
onConfirmed: () {
|
onConfirmed: () {
|
||||||
sendViewModel.commitTransaction(context);
|
sendViewModel.commitTransaction(context);
|
||||||
},
|
},
|
||||||
swiperText: "${S.of(context).swipe_to_send}");
|
swiperText: "${S.of(context).swipe_to_send}",
|
||||||
|
accessibleNavigationModeButtonText: S.of(context).send);
|
||||||
case IsExecutingState:
|
case IsExecutingState:
|
||||||
return LoadingBottomWidget(
|
return LoadingBottomWidget(
|
||||||
text: "${S.of(context).generating_transaction}...",
|
text: "${S.of(context).generating_transaction}...",
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ class WCConnectionRequestSheet extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
child: ConfirmSwiper(
|
child: ConfirmSwiper(
|
||||||
swiperText: S.of(context).wc_swipe_to_approve,
|
swiperText: S.of(context).wc_swipe_to_approve,
|
||||||
|
accessibleNavigationModeButtonText: S.of(context).wc_action_approve,
|
||||||
onConfirmed: () {
|
onConfirmed: () {
|
||||||
if (Navigator.canPop(context)) {
|
if (Navigator.canPop(context)) {
|
||||||
Navigator.of(context).pop(WCBottomSheetResult.one);
|
Navigator.of(context).pop(WCBottomSheetResult.one);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class WCSigningRequestSheet extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
child: ConfirmSwiper(
|
child: ConfirmSwiper(
|
||||||
swiperText: swipeLabel,
|
swiperText: swipeLabel,
|
||||||
|
accessibleNavigationModeButtonText: S.of(context).confirm,
|
||||||
onConfirmed: () {
|
onConfirmed: () {
|
||||||
if (Navigator.canPop(context)) {
|
if (Navigator.canPop(context)) {
|
||||||
Navigator.of(context).pop(WCBottomSheetResult.one);
|
Navigator.of(context).pop(WCBottomSheetResult.one);
|
||||||
|
|||||||
Reference in New Issue
Block a user