mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-12-11 17:14:32 -05:00
4f02435964
accessible theming/high contrast support
138 lines
4.4 KiB
Dart
138 lines
4.4 KiB
Dart
import 'package:awesome_extensions/awesome_extensions.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_translate/flutter_translate.dart';
|
|
import 'package:pinput/pinput.dart';
|
|
|
|
import '../theme/theme.dart';
|
|
|
|
class EnterPinDialog extends StatefulWidget {
|
|
const EnterPinDialog({
|
|
required this.reenter,
|
|
required this.description,
|
|
super.key,
|
|
});
|
|
|
|
final bool reenter;
|
|
final String? description;
|
|
|
|
@override
|
|
State<EnterPinDialog> createState() => _EnterPinDialogState();
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
super.debugFillProperties(properties);
|
|
properties
|
|
..add(StringProperty('description', description))
|
|
..add(DiagnosticsProperty<bool>('reenter', reenter));
|
|
}
|
|
}
|
|
|
|
class _EnterPinDialogState extends State<EnterPinDialog> {
|
|
final pinController = TextEditingController();
|
|
final focusNode = FocusNode();
|
|
final formKey = GlobalKey<FormState>();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
pinController.dispose();
|
|
focusNode.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
// ignore: prefer_expression_function_bodies
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
final scale = theme.extension<ScaleScheme>()!;
|
|
final focusedBorderColor = scale.primaryScale.hoverBorder;
|
|
final fillColor = scale.primaryScale.elementBackground;
|
|
final borderColor = scale.primaryScale.border;
|
|
|
|
final defaultPinTheme = PinTheme(
|
|
width: 56,
|
|
height: 60,
|
|
textStyle: TextStyle(fontSize: 22, color: scale.primaryScale.appText),
|
|
decoration: BoxDecoration(
|
|
color: fillColor,
|
|
borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(color: borderColor),
|
|
),
|
|
);
|
|
|
|
/// Optionally you can use form to validate the Pinput
|
|
return StyledDialog(
|
|
title: !widget.reenter
|
|
? translate('enter_pin_dialog.enter_pin')
|
|
: translate('enter_pin_dialog.reenter_pin'),
|
|
child: Form(
|
|
key: formKey,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Directionality(
|
|
// Specify direction if desired
|
|
textDirection: TextDirection.ltr,
|
|
child: Pinput(
|
|
controller: pinController,
|
|
focusNode: focusNode,
|
|
autofocus: true,
|
|
defaultPinTheme: defaultPinTheme,
|
|
enableSuggestions: false,
|
|
inputFormatters: <TextInputFormatter>[
|
|
FilteringTextInputFormatter.digitsOnly
|
|
],
|
|
hapticFeedbackType: HapticFeedbackType.lightImpact,
|
|
onCompleted: (pin) {
|
|
Navigator.pop(context, pin);
|
|
},
|
|
cursor: Column(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: [
|
|
Container(
|
|
margin: const EdgeInsets.only(bottom: 9),
|
|
width: 22,
|
|
height: 1,
|
|
color: focusedBorderColor,
|
|
),
|
|
],
|
|
),
|
|
focusedPinTheme: defaultPinTheme.copyWith(
|
|
height: 68,
|
|
width: 64,
|
|
decoration: defaultPinTheme.decoration!.copyWith(
|
|
border: Border.all(color: borderColor),
|
|
),
|
|
),
|
|
).paddingAll(16),
|
|
),
|
|
if (widget.description != null)
|
|
SizedBox(
|
|
width: 400,
|
|
child: Text(
|
|
widget.description!,
|
|
textAlign: TextAlign.center,
|
|
).paddingAll(16))
|
|
],
|
|
),
|
|
));
|
|
}
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
super.debugFillProperties(properties);
|
|
properties
|
|
..add(DiagnosticsProperty<TextEditingController>(
|
|
'pinController', pinController))
|
|
..add(DiagnosticsProperty<FocusNode>('focusNode', focusNode))
|
|
..add(DiagnosticsProperty<GlobalKey<FormState>>('formKey', formKey));
|
|
}
|
|
}
|