254 lines
8.8 KiB
Dart
254 lines
8.8 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:pin_code_fields/pin_code_fields.dart';
|
|
import 'package:wallpaperx/common/utils/shared_util.dart';
|
|
import 'package:wallpaperx/generated/assets.dart';
|
|
|
|
class PinCodeVerificationScreen extends StatefulWidget {
|
|
final Function callback;
|
|
final String checkPassword;
|
|
|
|
const PinCodeVerificationScreen({
|
|
super.key,
|
|
required this.callback,
|
|
required this.checkPassword,
|
|
});
|
|
|
|
@override
|
|
State<PinCodeVerificationScreen> createState() =>
|
|
_PinCodeVerificationScreenState();
|
|
}
|
|
|
|
class _PinCodeVerificationScreenState extends State<PinCodeVerificationScreen> {
|
|
var onTapRecognizer;
|
|
|
|
TextEditingController textEditingController = TextEditingController();
|
|
|
|
late StreamController<ErrorAnimationType> errorController;
|
|
|
|
bool hasError = false;
|
|
String currentText = "";
|
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
|
final formKey = GlobalKey<FormState>();
|
|
|
|
@override
|
|
void initState() {
|
|
onTapRecognizer = TapGestureRecognizer()
|
|
..onTap = () {
|
|
Navigator.pop(context);
|
|
};
|
|
errorController = StreamController<ErrorAnimationType>();
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
errorController.close();
|
|
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
key: scaffoldKey,
|
|
body: SafeArea(
|
|
child: Container(
|
|
margin: EdgeInsets.only(top: 94.w),
|
|
height: MediaQuery.of(context).size.height,
|
|
width: MediaQuery.of(context).size.width,
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Please input a',
|
|
style: TextStyle(
|
|
fontWeight: FontWeight.w700,
|
|
fontSize: 28.sp,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
Text(
|
|
'password',
|
|
style: TextStyle(
|
|
fontWeight: FontWeight.w700,
|
|
fontSize: 28.sp,
|
|
color: Colors.white,
|
|
),
|
|
)
|
|
],
|
|
),
|
|
Container(
|
|
clipBehavior: Clip.hardEdge,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15.r),
|
|
),
|
|
child: Image.asset(
|
|
Assets.imagesCustomLock,
|
|
width: 100.w,
|
|
height: 100.w,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 64.w),
|
|
Form(
|
|
key: formKey,
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 8,
|
|
horizontal: 30,
|
|
).w,
|
|
child: PinCodeTextField(
|
|
appContext: context,
|
|
pastedTextStyle: TextStyle(
|
|
color: Colors.green.shade600,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
dialogConfig: DialogConfig(platform: PinCodePlatform.iOS),
|
|
length: 4,
|
|
obscureText: true,
|
|
obscuringCharacter: '*',
|
|
animationType: AnimationType.fade,
|
|
pinTheme: PinTheme(
|
|
activeColor: const Color(0xff262626),
|
|
selectedColor: const Color(0xff262626),
|
|
selectedFillColor: Colors.grey,
|
|
inactiveFillColor: const Color(0xff262626),
|
|
errorBorderColor: const Color(0xff262626),
|
|
inactiveColor: const Color(0xff262626),
|
|
shape: PinCodeFieldShape.box,
|
|
borderRadius: BorderRadius.circular(30.r),
|
|
fieldHeight: 58.w,
|
|
fieldWidth: 58.w,
|
|
activeFillColor: hasError
|
|
? const Color(0xff262626)
|
|
: const Color(0xff262626),
|
|
),
|
|
showCursor: false,
|
|
animationDuration: const Duration(milliseconds: 300),
|
|
textStyle: TextStyle(
|
|
fontSize: 32.sp,
|
|
fontWeight: FontWeight.w700,
|
|
color: Colors.white,
|
|
height: 2.0,
|
|
),
|
|
backgroundColor: Colors.transparent,
|
|
enableActiveFill: true,
|
|
errorAnimationController: errorController,
|
|
controller: textEditingController,
|
|
keyboardType: TextInputType.number,
|
|
boxShadows: const [
|
|
BoxShadow(
|
|
offset: Offset(0, 1),
|
|
color: Colors.black12,
|
|
blurRadius: 30,
|
|
),
|
|
],
|
|
onCompleted: (v) {},
|
|
onChanged: (value) {
|
|
setState(() {
|
|
currentText = value;
|
|
});
|
|
},
|
|
beforeTextPaste: (text) {
|
|
setState(() {
|
|
currentText = text!;
|
|
});
|
|
return true;
|
|
},
|
|
)),
|
|
),
|
|
Visibility(
|
|
visible: widget.checkPassword == "",
|
|
child: Text(
|
|
"First input as password",
|
|
style: TextStyle(
|
|
color: Colors.red,
|
|
fontSize: 14.sp,
|
|
),
|
|
),
|
|
),
|
|
GestureDetector(
|
|
onTap: () {
|
|
formKey.currentState?.validate();
|
|
if (currentText.length == 4 && widget.checkPassword == "") {
|
|
UPCache.getInstance()
|
|
.setData("custom_password", currentText);
|
|
widget.callback();
|
|
} else if (currentText.length != 4 ||
|
|
currentText != widget.checkPassword) {
|
|
errorController.add(ErrorAnimationType
|
|
.shake); // Triggering error shake animation
|
|
setState(() {
|
|
hasError = true;
|
|
textEditingController.clear();
|
|
});
|
|
} else {
|
|
widget.callback();
|
|
setState(() {
|
|
hasError = false;
|
|
});
|
|
}
|
|
},
|
|
child: Container(
|
|
margin: const EdgeInsets.symmetric(
|
|
vertical: 24,
|
|
horizontal: 40,
|
|
).w,
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 17,
|
|
).w,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(30.r),
|
|
gradient: const LinearGradient(
|
|
begin: Alignment.topRight,
|
|
end: Alignment.bottomLeft,
|
|
colors: [
|
|
Color(0xffBEEF32),
|
|
Color(0xff2795E5),
|
|
Color(0xff8041FD),
|
|
],
|
|
),
|
|
),
|
|
child: Center(
|
|
child: Text(
|
|
"Confirm",
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 18.sp,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
GestureDetector(
|
|
child: Text(
|
|
"Clear",
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 18.sp,
|
|
),
|
|
),
|
|
onTap: () {
|
|
textEditingController.clear();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|