CakeWallet/lib/src/screens/pin_code/pin_code_widget.dart

314 lines
11 KiB
Dart
Raw Normal View History

2020-10-22 21:24:24 +03:00
import 'package:cake_wallet/utils/show_bar.dart';
2022-10-12 13:09:57 -04:00
// import 'package:flushbar/flushbar.dart';
2020-09-21 14:50:26 +03:00
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
class PinCodeWidget extends StatefulWidget {
PinCodeWidget(
2022-10-12 13:09:57 -04:00
{required Key key,
required this.onFullPin,
required this.initialPinLength,
required this.onChangedPin,
required this.hasLengthSwitcher,
this.onChangedPinLength,})
2020-09-21 14:50:26 +03:00
: super(key: key);
final void Function(String pin, PinCodeState state) onFullPin;
final void Function(String pin) onChangedPin;
2022-10-12 13:09:57 -04:00
final void Function(int length)? onChangedPinLength;
2020-09-21 14:50:26 +03:00
final bool hasLengthSwitcher;
final int initialPinLength;
@override
State<StatefulWidget> createState() => PinCodeState();
}
class PinCodeState<T extends PinCodeWidget> extends State<T> {
2022-10-12 13:09:57 -04:00
PinCodeState()
: _aspectRatio = 0,
pinLength = 0,
pin = '',
title = '';
2020-09-21 14:50:26 +03:00
static const defaultPinLength = fourPinLength;
static const sixPinLength = 6;
static const fourPinLength = 4;
final _gridViewKey = GlobalKey();
final _key = GlobalKey<ScaffoldState>();
int pinLength;
String pin;
String title;
double _aspectRatio;
2022-10-12 13:09:57 -04:00
// FIX-ME: Replace Flushbar
// Flushbar<void>? _progressBar;
2020-09-21 14:50:26 +03:00
int currentPinLength() => pin.length;
@override
void initState() {
super.initState();
pinLength = widget.initialPinLength;
pin = '';
title = S.current.enter_your_pin;
_aspectRatio = 0;
WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
}
void setTitle(String title) => setState(() => this.title = title);
void clear() => setState(() => pin = '');
void reset() => setState(() {
pin = '';
pinLength = widget.initialPinLength;
title = S.current.enter_your_pin;
});
void changePinLength(int length) {
setState(() {
pinLength = length;
pin = '';
});
widget.onChangedPinLength?.call(length);
}
void setDefaultPinLength() => changePinLength(widget.initialPinLength);
void calculateAspectRatio() {
final renderBox =
2022-10-12 13:09:57 -04:00
_gridViewKey.currentContext!.findRenderObject() as RenderBox;
2020-09-21 14:50:26 +03:00
final cellWidth = renderBox.size.width / 3;
final cellHeight = renderBox.size.height / 4;
if (cellWidth > 0 && cellHeight > 0) {
_aspectRatio = cellWidth / cellHeight;
}
setState(() {});
}
2020-10-22 21:24:24 +03:00
void changeProcessText(String text) {
hideProgressText();
2022-10-12 13:09:57 -04:00
// FIX-ME: Empty Duration,
// _progressBar = createBar<void>(text, duration: Duration())
// ..show(_key.currentContext);
2020-10-22 21:24:24 +03:00
}
2020-10-24 17:35:55 +03:00
void close() {
2022-10-12 13:09:57 -04:00
// _progressBar?.dismiss();
Navigator.of(_key.currentContext!).pop();
2020-10-24 17:35:55 +03:00
}
2020-10-22 21:24:24 +03:00
void hideProgressText() {
2022-10-12 13:09:57 -04:00
// _progressBar?.dismiss();
// _progressBar = null;
2020-10-22 21:24:24 +03:00
}
2020-09-21 14:50:26 +03:00
@override
2020-10-02 20:28:29 +03:00
Widget build(BuildContext context) => Scaffold(
key: _key, body: body(context), resizeToAvoidBottomInset: false);
2020-09-21 14:50:26 +03:00
Widget body(BuildContext context) {
final deleteIconImage = Image.asset(
'assets/images/delete_icon.png',
2022-10-12 13:09:57 -04:00
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
2020-09-21 14:50:26 +03:00
);
final faceImage = Image.asset(
'assets/images/face.png',
2022-10-12 13:09:57 -04:00
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
2020-09-21 14:50:26 +03:00
);
return Container(
color: Theme.of(context).backgroundColor,
padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0),
child: Column(children: <Widget>[
Spacer(flex: 2),
Text(title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
2022-10-12 13:09:57 -04:00
color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
2020-09-21 14:50:26 +03:00
Spacer(flex: 3),
Container(
width: 180,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(pinLength, (index) {
const size = 10.0;
final isFilled = pin.length > index ? pin[index] != null : false;
return Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isFilled
2022-10-12 13:09:57 -04:00
? Theme.of(context).primaryTextTheme!.headline6!.color!
2020-09-21 14:50:26 +03:00
: Theme.of(context)
2022-10-12 13:09:57 -04:00
.accentTextTheme!
.bodyText2!
.color!
2020-09-21 14:50:26 +03:00
.withOpacity(0.25),
));
}),
),
),
Spacer(flex: 2),
if (widget.hasLengthSwitcher) ...[
2022-10-12 13:09:57 -04:00
TextButton(
2020-09-21 14:50:26 +03:00
onPressed: () {
changePinLength(pinLength == PinCodeState.fourPinLength
? PinCodeState.sixPinLength
: PinCodeState.fourPinLength);
},
child: Text(
_changePinLengthText(),
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
color: Theme.of(context)
2022-10-12 13:09:57 -04:00
.accentTextTheme!
.bodyText2!
.decorationColor!),
2020-09-21 14:50:26 +03:00
))
],
Spacer(flex: 1),
Flexible(
flex: 24,
child: Container(
key: _gridViewKey,
child: _aspectRatio > 0
? GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: _aspectRatio,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(12, (index) {
const double marginRight = 15;
const double marginLeft = 15;
if (index == 9) {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
2022-10-12 13:09:57 -04:00
child: TextButton(
2020-09-21 14:50:26 +03:00
onPressed: () => null,
// (widget.hasLengthSwitcher ||
// !settingsStore
// .allowBiometricalAuthentication)
// ? null
// : () {
// FIXME
// if (authStore != null) {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// final biometricAuth = BiometricAuth();
// biometricAuth.isAuthenticated().then(
// (isAuth) {
// if (isAuth) {
// authStore.biometricAuth();
// _key.currentState.showSnackBar(
// SnackBar(
// content: Text(S.of(context).authenticated),
// backgroundColor: Colors.green,
// ),
// );
// }
// }
// );
// });
// }
// },
2022-10-12 13:09:57 -04:00
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: Container()
2020-09-21 14:50:26 +03:00
// (widget.hasLengthSwitcher ||
// !settingsStore
// .allowBiometricalAuthentication)
// ? Offstage()
// : faceImage,
),
);
} else if (index == 10) {
index = 0;
} else if (index == 11) {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
2022-10-12 13:09:57 -04:00
child: TextButton(
2020-09-21 14:50:26 +03:00
onPressed: () => _pop(),
2022-10-12 13:09:57 -04:00
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
2020-09-21 14:50:26 +03:00
child: deleteIconImage,
),
);
} else {
index++;
}
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
2022-10-12 13:09:57 -04:00
child: TextButton(
2020-09-21 14:50:26 +03:00
onPressed: () => _push(index),
2022-10-12 13:09:57 -04:00
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
2020-09-21 14:50:26 +03:00
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Theme.of(context)
2022-10-12 13:09:57 -04:00
.primaryTextTheme!
.headline6!
.color!)),
2020-09-21 14:50:26 +03:00
),
);
}),
)
: null))
]),
);
}
void _push(int num) {
setState(() {
if (currentPinLength() >= pinLength) {
return;
}
pin += num.toString();
widget.onChangedPin(pin);
if (pin.length == pinLength) {
widget.onFullPin(pin, this);
}
});
}
void _pop() {
if (currentPinLength() == 0) {
return;
}
2020-09-25 18:32:44 +03:00
setState(() => pin = pin.substring(0, pin.length - 1));
2020-09-21 14:50:26 +03:00
}
String _changePinLengthText() {
return S.current.use +
(pinLength == PinCodeState.fourPinLength
? '${PinCodeState.sixPinLength}'
: '${PinCodeState.fourPinLength}') +
S.current.digit_pin;
}
void _afterLayout(dynamic _) {
setDefaultPinLength();
calculateAspectRatio();
}
}