Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 7.3.0

* Added Biometrics support to the LoginOptions

## 7.2.0

* Added CustomSemantics widget that is used to wrap all the inputfields and buttons to make the component accessible for e2e testing.
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,44 @@ A package facilitating the basic ingredients for creating functional yet customi

To use this package, add `flutter_login` as a dependency in your pubspec.yaml file.


### Biometrics authentication
You can use faceID or fingerprint by adding:
```dart
loginWithBiometrics: true,
triggerBiometricsAutomatically: true,
```
to the `LoginOptions` object. This will trigger the biometrics authentication immediately when the EmailPasswordLoginForm is shown.

For the full biometrics setup you can follow the instructions in the [local_auth](https://pub.dev/packages/local_auth) package.

You need to add the following permissions to your AndroidManifest.xml file:

```xml
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
```

```java
import io.flutter.embedding.android.FlutterFragmentActivity;

public class MainActivity extends FlutterFragmentActivity {
// ...
}
```

or MainActivity.kt:

```kotlin
import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterFragmentActivity() {
// ...
}
```

to inherit from `FlutterFragmentActivity`.


## How to use

```dart
Expand Down
Binary file added assets/2.0x/ios_fingerprint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/3.0x/ios_fingerprint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ios_fingerprint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand All @@ -32,6 +34,7 @@ migrate_working_dir/
.pub/
/build/
.metadata
pubspec.lock

# Symbolication related
app.*.symbols
Expand Down
1 change: 1 addition & 0 deletions example/README.md
35 changes: 9 additions & 26 deletions example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,12 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
include: package:flutter_iconica_analysis/analysis_options.yaml

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
# https://dart-lang.github.io/linter/lints/index.html

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Possible to overwrite the rules from the package

analyzer:
plugins:
exclude:

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
linter:
rules:
93 changes: 44 additions & 49 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ignore_for_file: avoid_print

import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import "package:flutter/material.dart";
import "package:flutter_login/flutter_login.dart";

final loginOptions = LoginOptions(
emailDecoration: const InputDecoration(
Expand All @@ -15,21 +15,24 @@ final loginOptions = LoginOptions(
image: const FlutterLogo(
size: 200,
),
biometricsOptions: const LoginBiometricsOptions(
loginWithBiometrics: true,
triggerBiometricsAutomatically: false,
),
requestForgotPasswordButtonBuilder: (
context,
onPressed,
isDisabled,
onDisabledPress,
translations,
) {
return Opacity(
opacity: isDisabled ? 0.5 : 1.0,
child: ElevatedButton(
onPressed: isDisabled ? onDisabledPress : onPressed,
child: const Text('Send request'),
),
);
},
) =>
Opacity(
opacity: isDisabled ? 0.5 : 1.0,
child: ElevatedButton(
onPressed: isDisabled ? onDisabledPress : onPressed,
child: const Text("Send request"),
),
),
);

void main() {
Expand All @@ -40,54 +43,46 @@ class LoginExample extends StatelessWidget {
const LoginExample({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: const LoginScreen(),
);
}
Widget build(BuildContext context) => MaterialApp(
theme: ThemeData.dark(),
home: const LoginScreen(),
);
}

class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
body: EmailPasswordLoginForm(
title: const Text('Login Demo'),
options: loginOptions,
onLogin: (email, password) => print('$email:$password'),
onRegister: (email, password, ctx) => print('Register!'),
onForgotPassword: (email, ctx) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return const ForgotPasswordScreen();
},
),
);
},
),
);
}
Widget build(BuildContext context) => Scaffold(
body: EmailPasswordLoginForm(
title: const Text("Login Demo"),
options: loginOptions,
onLogin: (email, password) => print("$email:$password"),
onRegister: (email, password, ctx) => print("Register!"),
onForgotPassword: (email, ctx) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const ForgotPasswordScreen(),
),
);
},
),
);
}

class ForgotPasswordScreen extends StatelessWidget {
const ForgotPasswordScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ForgotPasswordForm(
options: loginOptions,
title: const Text('Forgot password'),
description: const Text('Hello world'),
onRequestForgotPassword: (email) {
print('Forgot password email sent to $email');
},
),
);
}
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(),
body: ForgotPasswordForm(
options: loginOptions,
title: const Text("Forgot password"),
description: const Text("Hello world"),
onRequestForgotPassword: (email) {
print("Forgot password email sent to $email");
},
),
);
}
Loading