mirror of
https://github.com/Iconica-Development/flutter_login_widget.git
synced 2025-05-18 21:23:44 +02:00
fix: added Ci and linter
This commit is contained in:
parent
15886ed5c3
commit
b1d379b321
12 changed files with 136 additions and 142 deletions
14
.github/workflows/component-ci.yml
vendored
Normal file
14
.github/workflows/component-ci.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
name: Iconica Standard Component CI Workflow
|
||||
# Workflow Caller version: 2.0.0
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-global-iconica-workflow:
|
||||
uses: Iconica-Development/.github/.github/workflows/component-ci.yml@master
|
||||
secrets: inherit
|
||||
permissions: write-all
|
||||
with:
|
||||
subfolder: "." # add optional subfolder to run workflow in
|
27
.github/workflows/flutter.yml
vendored
27
.github/workflows/flutter.yml
vendored
|
@ -1,27 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
/opt/hostedtoolcache/flutter
|
||||
key: ${{ runner.OS }}-flutter-install-cache
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Flutter format
|
||||
run: dart format -o none --set-exit-if-changed .
|
||||
- name: Flutter analyze
|
||||
run: flutter analyze
|
|
@ -1,3 +1,6 @@
|
|||
## 5.1.1
|
||||
* Added Ci and linter
|
||||
|
||||
## 5.1.0
|
||||
* Added the option to disable the showPassword button on the passwordfield.
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
include: package:flutter_lints/flutter.yaml
|
||||
include: package:flutter_iconica_analysis/analysis_options.yaml
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
# Possible to overwrite the rules from the package
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
///
|
||||
library flutter_login;
|
||||
|
||||
export 'src/config/spacer_options.dart';
|
||||
export 'src/config/login_options.dart';
|
||||
export 'src/config/spacer_options.dart';
|
||||
export 'src/service/login_validation.dart';
|
||||
export 'src/service/validation.dart';
|
||||
export 'src/widgets/email_password_login.dart';
|
||||
export 'src/widgets/forgot_password_form.dart';
|
||||
export 'src/service/validation.dart';
|
||||
export 'src/service/login_validation.dart';
|
||||
export 'src/widgets/mfa_widget.dart';
|
||||
|
|
|
@ -42,7 +42,8 @@ class LoginOptions {
|
|||
final Widget? title;
|
||||
final Widget? subtitle;
|
||||
|
||||
/// Option to modify the spacing between the title, subtitle, image, form, and button.
|
||||
/// Option to modify the spacing between the title, subtitle, image, form,
|
||||
/// and button.
|
||||
final LoginSpacerOptions spacers;
|
||||
|
||||
/// Maximum width of the form. Defaults to 400.
|
||||
|
@ -98,15 +99,14 @@ Widget _createLoginButton(
|
|||
bool disabled,
|
||||
OptionalAsyncCallback onDisabledPress,
|
||||
LoginOptions options,
|
||||
) {
|
||||
return Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.loginButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
) =>
|
||||
Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.loginButton),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _createForgotPasswordButton(
|
||||
BuildContext context,
|
||||
|
@ -114,15 +114,14 @@ Widget _createForgotPasswordButton(
|
|||
bool disabled,
|
||||
OptionalAsyncCallback onDisabledPress,
|
||||
LoginOptions options,
|
||||
) {
|
||||
return Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.forgotPasswordButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
) =>
|
||||
Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.forgotPasswordButton),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _createRequestForgotPasswordButton(
|
||||
BuildContext context,
|
||||
|
@ -130,15 +129,14 @@ Widget _createRequestForgotPasswordButton(
|
|||
bool disabled,
|
||||
OptionalAsyncCallback onDisabledPress,
|
||||
LoginOptions options,
|
||||
) {
|
||||
return Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.requestForgotPasswordButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
) =>
|
||||
Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.requestForgotPasswordButton),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _createRegisterButton(
|
||||
BuildContext context,
|
||||
|
@ -146,19 +144,19 @@ Widget _createRegisterButton(
|
|||
bool disabled,
|
||||
OptionalAsyncCallback onDisabledPress,
|
||||
LoginOptions options,
|
||||
) {
|
||||
return Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.registrationButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
) =>
|
||||
Opacity(
|
||||
opacity: disabled ? 0.5 : 1.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: !disabled ? onPressed : onDisabledPress,
|
||||
child: Text(options.translations.registrationButton),
|
||||
),
|
||||
);
|
||||
|
||||
typedef ButtonBuilder = Widget Function(
|
||||
BuildContext context,
|
||||
OptionalAsyncCallback onPressed,
|
||||
// ignore: avoid_positional_boolean_parameters
|
||||
bool isDisabled,
|
||||
OptionalAsyncCallback onDisabledPress,
|
||||
LoginOptions options,
|
||||
|
|
|
@ -30,6 +30,7 @@ class LoginSpacerOptions {
|
|||
/// Flex value for the spacer after the button.
|
||||
final int? spacerAfterButton;
|
||||
|
||||
/// Flex value for the form. Defaults to 1. Use this when also using the other spacer options.
|
||||
/// Flex value for the form. Defaults to 1. Use this when also using the
|
||||
/// other spacer options.
|
||||
final int formFlexValue;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ class LoginValidationService implements ValidationService {
|
|||
return options.translations.emailEmpty;
|
||||
}
|
||||
if (!RegExp(
|
||||
r"""(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])""")
|
||||
.hasMatch(value)) {
|
||||
r"""(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])""",
|
||||
).hasMatch(value)) {
|
||||
return options.translations.emailInvalid;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -5,9 +5,9 @@ import 'package:flutter_login/flutter_login.dart';
|
|||
|
||||
class EmailPasswordLoginForm extends StatefulWidget {
|
||||
const EmailPasswordLoginForm({
|
||||
required this.onLogin,
|
||||
super.key,
|
||||
this.onForgotPassword,
|
||||
required this.onLogin,
|
||||
this.onRegister,
|
||||
this.options = const LoginOptions(),
|
||||
});
|
||||
|
@ -40,7 +40,7 @@ class _EmailPasswordLoginFormState extends State<EmailPasswordLoginForm> {
|
|||
}
|
||||
|
||||
void _validate() {
|
||||
late bool isValid =
|
||||
late var isValid =
|
||||
widget.options.validations.validateEmail(_currentEmail) == null &&
|
||||
widget.options.validations.validatePassword(_currentPassword) ==
|
||||
null;
|
||||
|
@ -96,7 +96,7 @@ class _EmailPasswordLoginFormState extends State<EmailPasswordLoginForm> {
|
|||
options.title,
|
||||
theme.textTheme.headlineSmall,
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
if (options.spacers.spacerAfterTitle != null) ...[
|
||||
Spacer(flex: options.spacers.spacerAfterTitle!),
|
||||
|
@ -111,7 +111,7 @@ class _EmailPasswordLoginFormState extends State<EmailPasswordLoginForm> {
|
|||
options.subtitle,
|
||||
theme.textTheme.titleSmall,
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
if (options.spacers.spacerAfterSubtitle != null) ...[
|
||||
Spacer(flex: options.spacers.spacerAfterSubtitle!),
|
||||
|
@ -159,7 +159,7 @@ class _EmailPasswordLoginFormState extends State<EmailPasswordLoginForm> {
|
|||
keyboardType: TextInputType.visiblePassword,
|
||||
textInputAction: TextInputAction.done,
|
||||
style: options.passwordTextStyle,
|
||||
onFieldSubmitted: (_) => _handleLogin(),
|
||||
onFieldSubmitted: (_) async => _handleLogin(),
|
||||
decoration: options.passwordDecoration.copyWith(
|
||||
suffixIcon: options.showObscurePassword
|
||||
? IconButton(
|
||||
|
@ -199,22 +199,20 @@ class _EmailPasswordLoginFormState extends State<EmailPasswordLoginForm> {
|
|||
const SizedBox(height: 8),
|
||||
AnimatedBuilder(
|
||||
animation: _formValid,
|
||||
builder: (context, _) {
|
||||
return options.loginButtonBuilder(
|
||||
context,
|
||||
_handleLogin,
|
||||
!_formValid.value,
|
||||
() {
|
||||
_formKey.currentState?.validate();
|
||||
},
|
||||
options,
|
||||
);
|
||||
},
|
||||
builder: (context, _) => options.loginButtonBuilder(
|
||||
context,
|
||||
_handleLogin,
|
||||
!_formValid.value,
|
||||
() {
|
||||
_formKey.currentState?.validate();
|
||||
},
|
||||
options,
|
||||
),
|
||||
),
|
||||
if (widget.onRegister != null) ...[
|
||||
options.registrationButtonBuilder(
|
||||
context,
|
||||
() {
|
||||
() async {
|
||||
widget.onRegister?.call(
|
||||
_currentEmail,
|
||||
_currentPassword,
|
||||
|
|
|
@ -5,10 +5,10 @@ import 'package:flutter_login/flutter_login.dart';
|
|||
|
||||
class ForgotPasswordForm extends StatefulWidget {
|
||||
const ForgotPasswordForm({
|
||||
super.key,
|
||||
required this.options,
|
||||
required this.description,
|
||||
required this.onRequestForgotPassword,
|
||||
super.key,
|
||||
this.title,
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,7 @@ class _ForgotPasswordFormState extends State<ForgotPasswordForm> {
|
|||
}
|
||||
|
||||
void _validate() {
|
||||
late bool isValid =
|
||||
late var isValid =
|
||||
widget.options.validations.validateEmail(_currentEmail) == null;
|
||||
if (isValid != _formValid.value) {
|
||||
_formValid.value = isValid;
|
||||
|
@ -99,24 +99,22 @@ class _ForgotPasswordFormState extends State<ForgotPasswordForm> {
|
|||
),
|
||||
AnimatedBuilder(
|
||||
animation: _formValid,
|
||||
builder: (context, snapshot) {
|
||||
return Align(
|
||||
child: widget.options.requestForgotPasswordButtonBuilder(
|
||||
context,
|
||||
() {
|
||||
_formKey.currentState?.validate();
|
||||
if (_formValid.value) {
|
||||
widget.onRequestForgotPassword(_currentEmail);
|
||||
}
|
||||
},
|
||||
!_formValid.value,
|
||||
() {
|
||||
_formKey.currentState?.validate();
|
||||
},
|
||||
options,
|
||||
),
|
||||
);
|
||||
},
|
||||
builder: (context, snapshot) => Align(
|
||||
child: widget.options.requestForgotPasswordButtonBuilder(
|
||||
context,
|
||||
() async {
|
||||
_formKey.currentState?.validate();
|
||||
if (_formValid.value) {
|
||||
widget.onRequestForgotPassword(_currentEmail);
|
||||
}
|
||||
},
|
||||
!_formValid.value,
|
||||
() {
|
||||
_formKey.currentState?.validate();
|
||||
},
|
||||
options,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -22,6 +22,8 @@ class MFAWidget extends StatefulWidget {
|
|||
}) : assert(
|
||||
(onSubmitted == null && submitButtonBuilder == null) ||
|
||||
(onSubmitted != null && submitButtonBuilder != null),
|
||||
'onSubmitted and submitButtonBuilder must be both null or both'
|
||||
' not null',
|
||||
);
|
||||
|
||||
final Function(String code) onCompleted;
|
||||
|
@ -48,35 +50,33 @@ class _MFAWidgetState extends State<MFAWidget> {
|
|||
final TextEditingController _controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Pinput(
|
||||
defaultPinTheme: widget.defaultPinTheme,
|
||||
focusedPinTheme: widget.focusedPinTheme,
|
||||
submittedPinTheme: widget.submittedPinTheme,
|
||||
followingPinTheme: widget.followingPinTheme,
|
||||
disabledPinTheme: widget.disabledPinTheme,
|
||||
errorPinTheme: widget.errorPinTheme,
|
||||
separatorPositions: widget.seperatorPositions,
|
||||
errorBuilder: widget.errorBuilder,
|
||||
errorText: widget.errorText,
|
||||
errorTextStyle: widget.errorTextStyle,
|
||||
validator: widget.validator,
|
||||
controller: _controller,
|
||||
length: widget.length,
|
||||
onCompleted: (_) {
|
||||
widget.onCompleted(_controller.text);
|
||||
},
|
||||
),
|
||||
if (widget.onSubmitted != null &&
|
||||
widget.submitButtonBuilder != null) ...[
|
||||
widget.submitButtonBuilder!(() {
|
||||
widget.onSubmitted!(_controller.text);
|
||||
}),
|
||||
Widget build(BuildContext context) => Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Pinput(
|
||||
defaultPinTheme: widget.defaultPinTheme,
|
||||
focusedPinTheme: widget.focusedPinTheme,
|
||||
submittedPinTheme: widget.submittedPinTheme,
|
||||
followingPinTheme: widget.followingPinTheme,
|
||||
disabledPinTheme: widget.disabledPinTheme,
|
||||
errorPinTheme: widget.errorPinTheme,
|
||||
separatorPositions: widget.seperatorPositions,
|
||||
errorBuilder: widget.errorBuilder,
|
||||
errorText: widget.errorText,
|
||||
errorTextStyle: widget.errorTextStyle,
|
||||
validator: widget.validator,
|
||||
controller: _controller,
|
||||
length: widget.length,
|
||||
onCompleted: (_) {
|
||||
widget.onCompleted(_controller.text);
|
||||
},
|
||||
),
|
||||
if (widget.onSubmitted != null &&
|
||||
widget.submitButtonBuilder != null) ...[
|
||||
widget.submitButtonBuilder!(() {
|
||||
widget.onSubmitted!(_controller.text);
|
||||
}),
|
||||
],
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_login
|
||||
description: Flutter Login Component
|
||||
version: 5.1.0
|
||||
version: 5.1.1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.18.1 <3.0.0"
|
||||
|
@ -14,6 +14,9 @@ dependencies:
|
|||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
flutter_iconica_analysis:
|
||||
git:
|
||||
url: https://github.com/Iconica-Development/flutter_iconica_analysis
|
||||
ref: 6.0.0
|
||||
|
||||
flutter:
|
||||
|
|
Loading…
Reference in a new issue