Merge pull request #19 from Iconica-Development/feat/registration-progress-indicator

feat(registration): add progress indicator for on finish
This commit is contained in:
Freek van de Ven 2024-02-15 17:45:35 +01:00 committed by GitHub
commit 7a4bcd8b3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 184 additions and 162 deletions

View file

@ -3,6 +3,11 @@ SPDX-FileCopyrightText: 2022 Iconica
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
--> -->
# 2.0.1
- feat: added circular progress indicator while awaiting registration of user
- feat: added alignment option for buttons
# 2.0.0 # 2.0.0
- feat(buttons): Added the possiblity to only have a next button by return zero on the previous button builder - feat(buttons): Added the possiblity to only have a next button by return zero on the previous button builder
- feat: exposed input decoration in AuthTextField - feat: exposed input decoration in AuthTextField

View file

@ -26,6 +26,7 @@ class AuthScreen extends StatefulWidget {
this.formFlex, this.formFlex,
this.beforeTitleFlex, this.beforeTitleFlex,
this.afterTitleFlex, this.afterTitleFlex,
this.isLoading = false,
super.key, super.key,
}) : assert(steps.length > 0, 'At least one step is required'); }) : assert(steps.length > 0, 'At least one step is required');
@ -51,6 +52,7 @@ class AuthScreen extends StatefulWidget {
final int? formFlex; final int? formFlex;
final int? beforeTitleFlex; final int? beforeTitleFlex;
final int? afterTitleFlex; final int? afterTitleFlex;
final bool isLoading;
@override @override
State<AuthScreen> createState() => _AuthScreenState(); State<AuthScreen> createState() => _AuthScreenState();
@ -140,149 +142,151 @@ class _AuthScreenState extends State<AuthScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return widget.isLoading
backgroundColor: widget.customBackgroundColor ?? Colors.white, ? const Center(
appBar: _appBar, child: SizedBox(
body: Form( height: 120,
key: _formKey, width: 120,
child: PageView( child: CircularProgressIndicator(),
physics: const NeverScrollableScrollPhysics(), ),
controller: _pageController, )
children: <Widget>[ : Scaffold(
for (var i = 0; i < widget.steps.length; i++) backgroundColor: widget.customBackgroundColor ?? Colors.white,
Column( appBar: _appBar,
mainAxisSize: MainAxisSize.min, body: Form(
mainAxisAlignment: MainAxisAlignment.spaceBetween, key: _formKey,
children: [ child: PageView(
if (widget.titleWidget != null) ...[ physics: const NeverScrollableScrollPhysics(),
Expanded( controller: _pageController,
flex: widget.titleFlex ?? 1, children: <Widget>[
child: Column( for (var i = 0; i < widget.steps.length; i++)
mainAxisAlignment: MainAxisAlignment.start, Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ mainAxisAlignment: MainAxisAlignment.spaceBetween,
Spacer( children: [
flex: widget.beforeTitleFlex ?? 3, if (widget.titleWidget != null) ...[
), Expanded(
widget.titleWidget!, flex: widget.titleFlex ?? 1,
Spacer( child: Column(
flex: widget.afterTitleFlex ?? 2, mainAxisAlignment: MainAxisAlignment.start,
), mainAxisSize: MainAxisSize.min,
],
),
),
],
Flexible(
flex: widget.formFlex ?? 3,
child: Column(
children: [
for (AuthField field in widget.steps[i].fields)
Align(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (field.title != null) ...[
field.title!,
],
field.build(context, () {
_validate(i);
}),
],
),
),
],
),
),
Column(
children: [
Row(
mainAxisAlignment:
widget.buttonMainAxisAlignment != null
? widget.buttonMainAxisAlignment!
: (widget.previousButtonBuilder != null &&
widget.previousButtonBuilder?.call(
onPrevious,
widget.previousBtnTitle,
i,
) ==
null)
? MainAxisAlignment.start
: widget.steps.first != widget.steps[i]
? MainAxisAlignment.center
: MainAxisAlignment.end,
children: [
if (widget.previousButtonBuilder == null) ...[
if (widget.steps.first != widget.steps[i])
ElevatedButton(
onPressed: onPrevious,
child: Row(
children: [ children: [
const Icon( Expanded(
Icons.arrow_back, flex: widget.beforeTitleFlex ?? 3,
size: 18, child: Container(),
), ),
widget.titleWidget!,
Expanded(
flex: widget.afterTitleFlex ?? 2,
child: Container(),
),
],
),
),
Column(
children: [
Row(
mainAxisAlignment:
widget.buttonMainAxisAlignment != null
? widget.buttonMainAxisAlignment!
: (widget.previousButtonBuilder !=
null &&
widget.previousButtonBuilder
?.call(
onPrevious,
widget
.previousBtnTitle,
i,
) ==
null)
? MainAxisAlignment.start
: widget.steps.first !=
widget.steps[i]
? MainAxisAlignment.center
: MainAxisAlignment.end,
children: [
if (widget.previousButtonBuilder ==
null) ...[
if (widget.steps.first !=
widget.steps[i])
ElevatedButton(
onPressed: onPrevious,
child: Row(
children: [
const Icon(
Icons.arrow_back,
size: 18,
),
Padding(
padding:
const EdgeInsets.only(
left: 4.0),
child: Text(
widget.previousBtnTitle),
),
],
),
),
] else if (widget.previousButtonBuilder
?.call(onPrevious,
widget.previousBtnTitle, i) !=
null) ...[
widget.previousButtonBuilder!.call(
onPrevious,
widget.previousBtnTitle,
i)!
],
widget.nextButtonBuilder?.call(
!_formValid
? null
: () async {
await onNext(
widget.steps[i]);
},
widget.steps.last == widget.steps[i]
? widget.submitBtnTitle
: widget.nextBtnTitle,
i,
_formValid,
) ??
ElevatedButton(
onPressed: !_formValid
? null
: () async {
await onNext(
widget.steps[i]);
},
child: Row(
children: [
Text(
widget.steps.last ==
widget.steps[i]
? widget.submitBtnTitle
: widget.nextBtnTitle,
),
const Padding(
padding: EdgeInsets.only(
left: 4.0),
child: Icon(
Icons.arrow_forward,
size: 18,
),
),
],
),
),
],
),
if (widget.loginButton != null)
Padding( Padding(
padding: const EdgeInsets.only(left: 4.0), padding: const EdgeInsets.only(top: 20.0),
child: Text(widget.previousBtnTitle), child: widget.loginButton!,
), ),
], ],
),
), ),
] else if (widget.previousButtonBuilder?.call( ],
onPrevious, widget.previousBtnTitle, i) != ]),
null) ...[ ]),
widget.previousButtonBuilder! ));
.call(onPrevious, widget.previousBtnTitle, i)!
],
widget.nextButtonBuilder?.call(
!_formValid
? null
: () async {
await onNext(widget.steps[i]);
},
widget.steps.last == widget.steps[i]
? widget.submitBtnTitle
: widget.nextBtnTitle,
i,
_formValid,
) ??
ElevatedButton(
onPressed: !_formValid
? null
: () async {
await onNext(widget.steps[i]);
},
child: Row(
children: [
Text(
widget.steps.last == widget.steps[i]
? widget.submitBtnTitle
: widget.nextBtnTitle,
),
const Padding(
padding: EdgeInsets.only(left: 4.0),
child: Icon(
Icons.arrow_forward,
size: 18,
),
),
],
),
),
],
),
if (widget.loginButton != null)
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: widget.loginButton!,
),
],
),
],
),
],
),
),
);
} }
} }

View file

@ -1,61 +1,74 @@
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
import 'dart:collection'; import 'dart:collection';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_registration/flutter_registration.dart'; import 'package:flutter_registration/flutter_registration.dart';
import 'package:flutter_registration/src/auth_screen.dart'; import 'package:flutter_registration/src/auth_screen.dart';
class RegistrationScreen extends StatelessWidget { class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({ const RegistrationScreen({
required this.registrationOptions, required this.registrationOptions,
super.key, Key? key,
}); }) : super(key: key);
final RegistrationOptions registrationOptions; final RegistrationOptions registrationOptions;
Future<void> register({ @override
RegistrationScreenState createState() => RegistrationScreenState();
}
class RegistrationScreenState extends State<RegistrationScreen> {
bool _isLoading = false;
Future<void> _register({
required HashMap<String, dynamic> values, required HashMap<String, dynamic> values,
required void Function(int? pageToReturn) onError, required void Function(int? pageToReturn) onError,
}) async { }) async {
try { try {
var registered = setState(() {
await registrationOptions.registrationRepository.register(values); _isLoading = true;
});
var registered = await widget.registrationOptions.registrationRepository
.register(values);
if (registered == null) { if (registered == null) {
registrationOptions.afterRegistration(); widget.registrationOptions.afterRegistration();
} else { } else {
var pageToReturn = registrationOptions.onError?.call(registered); var pageToReturn = widget.registrationOptions.onError?.call(registered);
onError(pageToReturn); onError(pageToReturn);
} }
} catch (e) { } catch (e) {
onError(0); onError(0);
} finally {
setState(() {
_isLoading = false;
});
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var translations = registrationOptions.registrationTranslations; var translations = widget.registrationOptions.registrationTranslations;
return AuthScreen( return AuthScreen(
steps: registrationOptions.registrationSteps, steps: widget.registrationOptions.registrationSteps,
customAppBar: registrationOptions.customAppbarBuilder?.call( customAppBar: widget.registrationOptions.customAppbarBuilder?.call(
translations.title, translations.title,
), ),
onFinish: register, onFinish: _register,
appBarTitle: translations.title, appBarTitle: translations.title,
submitBtnTitle: translations.registerBtn, submitBtnTitle: translations.registerBtn,
nextBtnTitle: translations.nextStepBtn, nextBtnTitle: translations.nextStepBtn,
previousBtnTitle: translations.previousStepBtn, previousBtnTitle: translations.previousStepBtn,
nextButtonBuilder: registrationOptions.nextButtonBuilder, nextButtonBuilder: widget.registrationOptions.nextButtonBuilder,
previousButtonBuilder: registrationOptions.previousButtonBuilder, previousButtonBuilder: widget.registrationOptions.previousButtonBuilder,
buttonMainAxisAlignment: registrationOptions.buttonMainAxisAlignment, buttonMainAxisAlignment:
customBackgroundColor: registrationOptions.backgroundColor, widget.registrationOptions.buttonMainAxisAlignment,
titleWidget: registrationOptions.titleWidget, customBackgroundColor: widget.registrationOptions.backgroundColor,
loginButton: registrationOptions.loginButton, titleWidget: widget.registrationOptions.titleWidget,
loginButton: widget.registrationOptions.loginButton,
isLoading: _isLoading,
); );
} }
} }

View file

@ -4,7 +4,7 @@
name: flutter_registration name: flutter_registration
description: A Flutter Registration package description: A Flutter Registration package
version: 2.0.0 version: 2.0.1
repository: https://github.com/Iconica-Development/flutter_registration repository: https://github.com/Iconica-Development/flutter_registration
publish_to: none publish_to: none