· 5 years ago · Sep 01, 2020, 06:50 AM
1import 'dart:async';
2
3import 'package:flutter/cupertino.dart';
4import 'package:flutter/foundation.dart';
5import 'package:flutter/material.dart';
6
7class Otp extends StatefulWidget {
8 final String email;
9 final String newEmail;
10 final bool isGuestCheckOut;
11
12 const Otp({
13 Key key,
14 @required this.email,
15 this.newEmail = "",
16 this.isGuestCheckOut,
17 }) : super(key: key);
18
19 @override
20 _OtpState createState() => new _OtpState();
21}
22
23class _OtpState extends State<Otp> with SingleTickerProviderStateMixin {
24 // Constants
25 final int time = 30;
26 AnimationController _controller;
27
28 // Variables
29 Size _screenSize;
30 int _currentDigit;
31 int _firstDigit;
32 int _secondDigit;
33 int _thirdDigit;
34 int _fourthDigit;
35
36 Timer timer;
37 int totalTimeInSeconds;
38 bool _hideResendButton;
39
40 String userName = "";
41 bool didReadNotifications = false;
42 int unReadNotificationsCount = 0;
43
44 // Returns "Appbar"
45 get _getAppbar {
46 return new AppBar(
47 backgroundColor: Colors.transparent,
48 elevation: 0.0,
49 leading: new InkWell(
50 borderRadius: BorderRadius.circular(30.0),
51 child: new Icon(
52 Icons.arrow_back,
53 color: Colors.black54,
54 ),
55 onTap: () {
56 Navigator.pop(context);
57 },
58 ),
59 centerTitle: true,
60 );
61 }
62
63 // Return "Verification Code" label
64 get _getVerificationCodeLabel {
65 return new Text(
66 "Verification Code",
67 textAlign: TextAlign.center,
68 style: new TextStyle(
69 fontSize: 28.0, color: Colors.black, fontWeight: FontWeight.bold),
70 );
71 }
72
73 // Return "Email" label
74 get _getEmailLabel {
75 return new Text(
76 "Please enter the OTP sent\non your registered Email ID.",
77 textAlign: TextAlign.center,
78 style: new TextStyle(
79 fontSize: 18.0, color: Colors.black, fontWeight: FontWeight.w600),
80 );
81 }
82
83 // Return "OTP" input field
84 get _getInputField {
85 return new Row(
86 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
87 children: <Widget>[
88 _otpTextField(_firstDigit),
89 _otpTextField(_secondDigit),
90 _otpTextField(_thirdDigit),
91 _otpTextField(_fourthDigit),
92 ],
93 );
94 }
95
96 // Returns "OTP" input part
97 get _getInputPart {
98 return new Column(
99 mainAxisSize: MainAxisSize.max,
100 mainAxisAlignment: MainAxisAlignment.spaceBetween,
101 children: <Widget>[
102 _getVerificationCodeLabel,
103 _getEmailLabel,
104 _getInputField,
105 _hideResendButton ? _getTimerText : _getResendButton,
106 _getOtpKeyboard
107 ],
108 );
109 }
110
111 // Returns "Timer" label
112 get _getTimerText {
113 return Container(
114 height: 32,
115 child: new Offstage(
116 offstage: !_hideResendButton,
117 child: Row(
118 mainAxisAlignment: MainAxisAlignment.center,
119 children: <Widget>[
120 new Icon(Icons.access_time),
121 new SizedBox(
122 width: 5.0,
123 ),
124 OtpTimer(_controller, 15.0, Colors.black)
125 ],
126 ),
127 ),
128 );
129 }
130
131 // Returns "Resend" button
132 get _getResendButton {
133 return new InkWell(
134 child: new Container(
135 height: 32,
136 width: 120,
137 decoration: BoxDecoration(
138 color: Colors.black,
139 shape: BoxShape.rectangle,
140 borderRadius: BorderRadius.circular(32)),
141 alignment: Alignment.center,
142 child: new Text(
143 "Resend OTP",
144 style:
145 new TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
146 ),
147 ),
148 onTap: () {
149 // Resend you OTP via API or anything
150 },
151 );
152 }
153
154 // Returns "Otp" keyboard
155 get _getOtpKeyboard {
156 return new Container(
157 height: _screenSize.width - 80,
158 child: new Column(
159 children: <Widget>[
160 new Expanded(
161 child: new Row(
162 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
163 children: <Widget>[
164 _otpKeyboardInputButton(
165 label: "1",
166 onPressed: () {
167 _setCurrentDigit(1);
168 }),
169 _otpKeyboardInputButton(
170 label: "2",
171 onPressed: () {
172 _setCurrentDigit(2);
173 }),
174 _otpKeyboardInputButton(
175 label: "3",
176 onPressed: () {
177 _setCurrentDigit(3);
178 }),
179 ],
180 ),
181 ),
182 new Expanded(
183 child: new Row(
184 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
185 children: <Widget>[
186 _otpKeyboardInputButton(
187 label: "4",
188 onPressed: () {
189 _setCurrentDigit(4);
190 }),
191 _otpKeyboardInputButton(
192 label: "5",
193 onPressed: () {
194 _setCurrentDigit(5);
195 }),
196 _otpKeyboardInputButton(
197 label: "6",
198 onPressed: () {
199 _setCurrentDigit(6);
200 }),
201 ],
202 ),
203 ),
204 new Expanded(
205 child: new Row(
206 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
207 children: <Widget>[
208 _otpKeyboardInputButton(
209 label: "7",
210 onPressed: () {
211 _setCurrentDigit(7);
212 }),
213 _otpKeyboardInputButton(
214 label: "8",
215 onPressed: () {
216 _setCurrentDigit(8);
217 }),
218 _otpKeyboardInputButton(
219 label: "9",
220 onPressed: () {
221 _setCurrentDigit(9);
222 }),
223 ],
224 ),
225 ),
226 new Expanded(
227 child: new Row(
228 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
229 children: <Widget>[
230 new SizedBox(
231 width: 80.0,
232 ),
233 _otpKeyboardInputButton(
234 label: "0",
235 onPressed: () {
236 _setCurrentDigit(0);
237 }),
238 _otpKeyboardActionButton(
239 label: new Icon(
240 Icons.backspace,
241 color: Colors.black,
242 ),
243 onPressed: () {
244 setState(() {
245 if (_fourthDigit != null) {
246 _fourthDigit = null;
247 } else if (_thirdDigit != null) {
248 _thirdDigit = null;
249 } else if (_secondDigit != null) {
250 _secondDigit = null;
251 } else if (_firstDigit != null) {
252 _firstDigit = null;
253 }
254 });
255 }),
256 ],
257 ),
258 ),
259 ],
260 ));
261 }
262
263 // Overridden methods
264 @override
265 void initState() {
266 totalTimeInSeconds = time;
267 super.initState();
268 _controller =
269 AnimationController(vsync: this, duration: Duration(seconds: time))
270 ..addStatusListener((status) {
271 if (status == AnimationStatus.dismissed) {
272 setState(() {
273 _hideResendButton = !_hideResendButton;
274 });
275 }
276 });
277 _controller.reverse(
278 from: _controller.value == 0.0 ? 1.0 : _controller.value);
279 _startCountdown();
280 }
281
282 @override
283 void dispose() {
284 _controller.dispose();
285 super.dispose();
286 }
287
288 @override
289 Widget build(BuildContext context) {
290 _screenSize = MediaQuery.of(context).size;
291 return new Scaffold(
292 appBar: _getAppbar,
293 backgroundColor: Colors.white,
294 body: new Container(
295 width: _screenSize.width,
296// padding: new EdgeInsets.only(bottom: 16.0),
297 child: _getInputPart,
298 ),
299 );
300 }
301
302 // Returns "Otp custom text field"
303 Widget _otpTextField(int digit) {
304 return new Container(
305 width: 35.0,
306 height: 45.0,
307 alignment: Alignment.center,
308 child: new Text(
309 digit != null ? digit.toString() : "",
310 style: new TextStyle(
311 fontSize: 30.0,
312 color: Colors.black,
313 ),
314 ),
315 decoration: BoxDecoration(
316// color: Colors.grey.withOpacity(0.4),
317 border: Border(
318 bottom: BorderSide(
319 width: 2.0,
320 color: Colors.black,
321 ))),
322 );
323 }
324
325 // Returns "Otp keyboard input Button"
326 Widget _otpKeyboardInputButton({String label, VoidCallback onPressed}) {
327 return new Material(
328 color: Colors.transparent,
329 child: new InkWell(
330 onTap: onPressed,
331 borderRadius: new BorderRadius.circular(40.0),
332 child: new Container(
333 height: 80.0,
334 width: 80.0,
335 decoration: new BoxDecoration(
336 shape: BoxShape.circle,
337 ),
338 child: new Center(
339 child: new Text(
340 label,
341 style: new TextStyle(
342 fontSize: 30.0,
343 color: Colors.black,
344 ),
345 ),
346 ),
347 ),
348 ),
349 );
350 }
351
352 // Returns "Otp keyboard action Button"
353 _otpKeyboardActionButton({Widget label, VoidCallback onPressed}) {
354 return new InkWell(
355 onTap: onPressed,
356 borderRadius: new BorderRadius.circular(40.0),
357 child: new Container(
358 height: 80.0,
359 width: 80.0,
360 decoration: new BoxDecoration(
361 shape: BoxShape.circle,
362 ),
363 child: new Center(
364 child: label,
365 ),
366 ),
367 );
368 }
369
370 // Current digit
371 void _setCurrentDigit(int i) {
372 setState(() {
373 _currentDigit = i;
374 if (_firstDigit == null) {
375 _firstDigit = _currentDigit;
376 } else if (_secondDigit == null) {
377 _secondDigit = _currentDigit;
378 } else if (_thirdDigit == null) {
379 _thirdDigit = _currentDigit;
380 } else if (_fourthDigit == null) {
381 _fourthDigit = _currentDigit;
382
383 var otp = _firstDigit.toString() +
384 _secondDigit.toString() +
385 _thirdDigit.toString() +
386 _fourthDigit.toString();
387
388 // Verify your otp by here. API call
389 }
390 });
391 }
392
393 Future<Null> _startCountdown() async {
394 setState(() {
395 _hideResendButton = true;
396 totalTimeInSeconds = time;
397 });
398 _controller.reverse(
399 from: _controller.value == 0.0 ? 1.0 : _controller.value);
400 }
401
402 void clearOtp() {
403 _fourthDigit = null;
404 _thirdDigit = null;
405 _secondDigit = null;
406 _firstDigit = null;
407 setState(() {});
408 }
409}
410
411