Skip to content

Commit 6dbf155

Browse files
committed
chore: update dependencies, support initial values, and improve form messages
1 parent 805bc41 commit 6dbf155

21 files changed

Lines changed: 752 additions & 369 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
## 0.0.13
2+
3+
- dependencies updated
4+
- initial values supported
5+
- extra dependencies removed
6+
17
## 0.0.12
8+
29
- dependencies updated
310
- If you need SMS autofill on Android, you need to add the smart_auth (or similar) package directly to your project.
411
- https://github.com/Tkko/Flutter_PinPut/blob/master/MIGRATION.md

example/lib/main.dart

Lines changed: 124 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,150 @@
1+
import 'package:flutter/foundation.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter/services.dart';
34
import 'package:flutter_animated_login/flutter_animated_login.dart';
45

56
void main() {
6-
runApp(const MyApp());
7+
runApp(
8+
const MaterialApp(
9+
title: 'Flutter Animated Login',
10+
debugShowCheckedModeBanner: false,
11+
home: MyApp(),
12+
),
13+
);
714
}
815

9-
ValueNotifier<bool> isDark = ValueNotifier<bool>(true);
16+
ValueNotifier<bool> loginTypeNotifier = ValueNotifier<bool>(true);
1017

1118
class MyApp extends StatelessWidget {
1219
const MyApp({super.key});
1320

21+
@override
22+
Widget build(BuildContext context) {
23+
return Scaffold(
24+
body: Center(
25+
child: ElevatedButton(
26+
onPressed: () {
27+
Navigator.push(
28+
context,
29+
MaterialPageRoute(
30+
builder: (context) => const LoginDemoApp(),
31+
),
32+
);
33+
},
34+
child: const Text("Login"),
35+
),
36+
),
37+
);
38+
}
39+
}
40+
41+
class LoginDemoApp extends StatefulWidget {
42+
const LoginDemoApp({super.key});
43+
44+
@override
45+
State<LoginDemoApp> createState() => _LoginDemoAppState();
46+
}
47+
48+
class _LoginDemoAppState extends State<LoginDemoApp> {
49+
late TextFieldController _controller;
50+
late TextFieldController _otpController;
51+
52+
@override
53+
void initState() {
54+
_controller = TextFieldController();
55+
_otpController = TextFieldController();
56+
if (kDebugMode) {
57+
_controller.text = '7012345678';
58+
_otpController.text = '123452';
59+
}
60+
super.initState();
61+
}
62+
63+
@override
64+
void dispose() {
65+
_controller.isDisposed ? null : _controller.dispose();
66+
super.dispose();
67+
}
68+
1469
@override
1570
Widget build(BuildContext context) {
1671
return ValueListenableBuilder(
17-
valueListenable: isDark,
18-
builder: (context, value, child) => MaterialApp(
19-
title: 'Flutter Animated Login',
20-
themeMode: value ? ThemeMode.dark : ThemeMode.light,
21-
theme: value ? ThemeData.dark() : ThemeData.dark(),
22-
debugShowCheckedModeBanner: false,
23-
home: Scaffold(
24-
floatingActionButton: FilledButton(
25-
onPressed: () => isDark.value = !isDark.value,
26-
child: value
27-
? const Text("Login with OTP")
28-
: const Text("Login with Password"),
29-
),
30-
body: FlutterAnimatedLogin(
31-
loginType: value ? LoginType.password : LoginType.otp,
32-
onLogin: (loginData) async {
72+
valueListenable: loginTypeNotifier,
73+
builder: (context, value, child) => Scaffold(
74+
floatingActionButton: FilledButton(
75+
onPressed: () {
76+
loginTypeNotifier.value = !loginTypeNotifier.value;
77+
},
78+
child: value
79+
? const Text("Login with OTP")
80+
: const Text("Login with Password"),
81+
),
82+
body: FlutterAnimatedLogin(
83+
loginType: value ? LoginType.password : LoginType.otp,
84+
onLogin: (loginData) async {
85+
if (loginData.name == '+917012345678') {
86+
final result = await Future.delayed(
87+
const Duration(seconds: 2),
88+
() => '',
89+
);
90+
SystemChannels.textInput.invokeMethod('TextInput.hide');
91+
TextInput.finishAutofillContext();
92+
return result;
93+
} else {
94+
return 'Invalid phone number, please try again.';
95+
}
96+
},
97+
onVerify: (otp) async {
98+
if (otp.secret == '123456') {
3399
final result = await Future.delayed(
34100
const Duration(seconds: 2),
35101
() => '',
36102
);
37103
SystemChannels.textInput.invokeMethod('TextInput.hide');
38104
TextInput.finishAutofillContext();
39105
return result;
40-
},
41-
loginConfig: const LoginConfig(
42-
logo: FlutterLogo(size: 100),
43-
title: 'Mohesu Enterprises',
44-
subtitle: 'Let\'s Sign In',
106+
} else {
107+
return 'Invalid OTP, please try again.';
108+
}
109+
},
110+
loginConfig: LoginConfig(
111+
title: 'Mohesu Enterprises',
112+
subtitle: 'Let\'s Sign In',
113+
textFiledConfig: EmailPhoneTextFiledConfig(
114+
controller: _controller,
45115
),
46-
providers: [
47-
LoginProvider(
48-
icon: Icons.reddit,
49-
label: 'Reddit',
50-
callback: () async {
51-
return "";
52-
},
53-
),
54-
LoginProvider(
55-
icon: Icons.apple,
56-
label: 'Apple',
57-
callback: () async {
58-
return "";
59-
},
60-
),
61-
LoginProvider(
62-
icon: Icons.facebook,
63-
label: 'Facebook',
64-
callback: () async {
65-
return "";
66-
},
67-
),
68-
],
69116
),
117+
verifyConfig: VerifyConfig(
118+
textFiledConfig: OtpTextFiledConfig(
119+
controller: _otpController,
120+
),
121+
),
122+
providers: [
123+
LoginProvider(
124+
icon: Icons.reddit,
125+
label: const Text('Reddit'),
126+
callback: () async {
127+
await Future.delayed(const Duration(seconds: 3), () {
128+
print('Reddit login');
129+
});
130+
return "";
131+
},
132+
),
133+
LoginProvider(
134+
icon: Icons.apple,
135+
label: const Text('Apple'),
136+
callback: () async {
137+
return "";
138+
},
139+
),
140+
LoginProvider(
141+
icon: Icons.facebook,
142+
label: const Text('Facebook'),
143+
callback: () async {
144+
return "";
145+
},
146+
),
147+
],
70148
),
71149
),
72150
);

example/test/widget_test.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
// gestures. You can also use WidgetTester to find child widgets in the widget
66
// tree, read text, and verify that the values of widget properties are correct.
77

8+
import 'package:example/main.dart';
89
import 'package:flutter/material.dart';
910
import 'package:flutter_test/flutter_test.dart';
1011

11-
import 'package:example/main.dart';
12-
1312
void main() {
1413
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
1514
// Build our app and trigger a frame.
16-
await tester.pumpWidget(const MyApp());
15+
await tester.pumpWidget(const LoginDemoApp());
1716

1817
// Verify that our counter starts at 0.
1918
expect(find.text('0'), findsOneWidget);

lib/flutter_animated_login.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
library;
22

3+
import 'package:flutter/material.dart';
4+
35
export 'package:flutter_intl_phone_field/flutter_intl_phone_field.dart';
46
export 'package:pinput/pinput.dart';
57

@@ -17,3 +19,15 @@ export 'src/utils/verify_config.dart';
1719
export 'src/verify.dart';
1820
export 'src/widget/page.dart';
1921
export 'src/widget/title.dart';
22+
23+
class TextFieldController extends TextEditingController {
24+
bool _isDisposed = false;
25+
26+
@override
27+
void dispose() {
28+
_isDisposed = true;
29+
super.dispose();
30+
}
31+
32+
bool get isDisposed => _isDisposed;
33+
}

0 commit comments

Comments
 (0)