mirror of
https://github.com/Iconica-Development/flutter_login_widget.git
synced 2025-05-19 13:43:44 +02:00
autologin
This commit is contained in:
parent
9d6529538d
commit
7abc81593b
14 changed files with 222 additions and 432 deletions
|
@ -1,42 +1,15 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../login_config.dart';
|
import '../login_config.dart';
|
||||||
import '../model/login_confirmation_result.dart';
|
import '../model/login_confirmation_result.dart';
|
||||||
import '../model/login_user.dart';
|
import '../model/login_user.dart';
|
||||||
|
|
||||||
abstract class LoginRepository with ChangeNotifier {
|
abstract class LoginRepository {
|
||||||
String? _loggedIn = '';
|
bool loggedIn = false;
|
||||||
String loginError = '';
|
String loginError = '';
|
||||||
bool _initialized = false;
|
|
||||||
|
|
||||||
bool isInitialized() => _initialized;
|
|
||||||
|
|
||||||
/// This function returns true if the user is logged in.
|
|
||||||
bool isLoggedIn() => _loggedIn != null && _loggedIn != '';
|
|
||||||
String get user => _loggedIn!;
|
|
||||||
|
|
||||||
/// This function sets the logged in user.
|
|
||||||
void setLoggedIn(String user) => _loggedIn = user;
|
|
||||||
|
|
||||||
String getLoginError() => loginError;
|
String getLoginError() => loginError;
|
||||||
|
|
||||||
Future<bool> login(String username, String password);
|
Future<bool> login(String username, String password);
|
||||||
|
|
||||||
Future<void> logout() async {
|
|
||||||
_loggedIn = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function returns a map with the username.
|
|
||||||
Map<String, dynamic> getUser() => {
|
|
||||||
'username': _loggedIn,
|
|
||||||
};
|
|
||||||
|
|
||||||
@mustCallSuper
|
|
||||||
Future<void> init() async {
|
|
||||||
// Auto login here
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<LoginUser?> signInWithSocial(SocialLoginBundle bundle);
|
Future<LoginUser?> signInWithSocial(SocialLoginBundle bundle);
|
||||||
Future<bool?> userprofileExists();
|
Future<bool?> userprofileExists();
|
||||||
Future sendLoginEmail(String input);
|
Future sendLoginEmail(String input);
|
||||||
|
@ -59,6 +32,6 @@ abstract class LoginRepository with ChangeNotifier {
|
||||||
});
|
});
|
||||||
Future<bool> forgotPassword(String email);
|
Future<bool> forgotPassword(String email);
|
||||||
Future<bool> isRegistrationRequired(LoginUser user);
|
Future<bool> isRegistrationRequired(LoginUser user);
|
||||||
Future<void> reLogin();
|
Future<void> reLogin({required VoidCallback onLoggedIn});
|
||||||
Future<LoginUser?> signInAnonymous();
|
Future<LoginUser?> signInAnonymous();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import 'sdk/screen.dart';
|
|
||||||
import 'sdk/user.dart';
|
|
||||||
|
|
||||||
mixin FlutterLoginSdk {
|
|
||||||
static final UserService _userService = UserService();
|
|
||||||
static final ScreenService _screenService = ScreenService();
|
|
||||||
|
|
||||||
UserService get users => _userService;
|
|
||||||
ScreenService get screens => _screenService;
|
|
||||||
|
|
||||||
static UserService get userService => _userService;
|
|
||||||
static ScreenService get screenService => _screenService;
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_userService.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,10 +2,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_login/backend/login_repository.dart';
|
import 'package:flutter_login/backend/login_repository.dart';
|
||||||
import '../default_translation.dart';
|
import '../default_translation.dart';
|
||||||
import '../plugins/login/login_email_password.dart';
|
import '../plugins/login/login_email_password.dart';
|
||||||
import 'flutter_login_sdk.dart';
|
|
||||||
import 'login_config.dart';
|
import 'login_config.dart';
|
||||||
import 'plugins/login/choose_login.dart';
|
import 'plugins/login/choose_login.dart';
|
||||||
import 'widgets/custom_navigator.dart';
|
|
||||||
export '../plugins/form/form.dart';
|
export '../plugins/form/form.dart';
|
||||||
export '../plugins/login/email_password_form.dart';
|
export '../plugins/login/email_password_form.dart';
|
||||||
export '../plugins/login/login_email_password.dart';
|
export '../plugins/login/login_email_password.dart';
|
||||||
|
@ -15,8 +13,8 @@ export 'model/login_confirmation_result.dart';
|
||||||
export 'model/login_user.dart';
|
export 'model/login_user.dart';
|
||||||
export 'plugins/settings/control.dart' show Control;
|
export 'plugins/settings/control.dart' show Control;
|
||||||
|
|
||||||
class FlutterLogin extends InheritedWidget with FlutterLoginSdk {
|
class FlutterLogin extends InheritedWidget {
|
||||||
FlutterLogin({
|
const FlutterLogin({
|
||||||
required this.config,
|
required this.config,
|
||||||
required this.repository,
|
required this.repository,
|
||||||
required Widget child,
|
required Widget child,
|
||||||
|
@ -24,14 +22,6 @@ class FlutterLogin extends InheritedWidget with FlutterLoginSdk {
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key, child: child);
|
}) : super(key: key, child: child);
|
||||||
|
|
||||||
FlutterLogin.from({
|
|
||||||
required FlutterLogin appShell,
|
|
||||||
required Widget child,
|
|
||||||
Key? key,
|
|
||||||
}) : config = appShell.config,
|
|
||||||
repository = appShell.repository,
|
|
||||||
app = appShell.app,
|
|
||||||
super(child: child, key: key);
|
|
||||||
static Function(Object?) logError = (error) {};
|
static Function(Object?) logError = (error) {};
|
||||||
static Map<String, Map<String, String>> get defaultTranslations =>
|
static Map<String, Map<String, String>> get defaultTranslations =>
|
||||||
defaultTranslation;
|
defaultTranslation;
|
||||||
|
@ -41,21 +31,21 @@ class FlutterLogin extends InheritedWidget with FlutterLoginSdk {
|
||||||
final Widget app;
|
final Widget app;
|
||||||
|
|
||||||
static FlutterLogin of(BuildContext context) {
|
static FlutterLogin of(BuildContext context) {
|
||||||
var inheritedAppshell =
|
var inheritedLogin =
|
||||||
context.dependOnInheritedWidgetOfExactType<FlutterLogin>();
|
context.dependOnInheritedWidgetOfExactType<FlutterLogin>();
|
||||||
if (inheritedAppshell == null) {
|
if (inheritedLogin == null) {
|
||||||
throw FlutterError(
|
throw FlutterError(
|
||||||
'You are retrieving an flutter login from a context that does not contain an flutter login. Make sure you keep the flutter login in your inheritence tree',
|
'You are retrieving an flutter login from a context that does not contain an flutter login. Make sure you keep the flutter login in your inheritence tree',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return inheritedAppshell;
|
return inheritedLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(FlutterLogin oldWidget) => config != oldWidget.config;
|
bool updateShouldNotify(FlutterLogin oldWidget) => config != oldWidget.config;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppShellRetrieval on BuildContext {
|
extension LoginRetrieval on BuildContext {
|
||||||
static LoginRepository? _cachedBackend;
|
static LoginRepository? _cachedBackend;
|
||||||
FlutterLogin login() => FlutterLogin.of(this);
|
FlutterLogin login() => FlutterLogin.of(this);
|
||||||
LoginRepository loginRepository() {
|
LoginRepository loginRepository() {
|
||||||
|
@ -77,7 +67,7 @@ extension StringFormat on String {
|
||||||
String format(List<dynamic> params) => _interpolate(this, params);
|
String format(List<dynamic> params) => _interpolate(this, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppShellTranslate on BuildContext {
|
extension LoginTranslate on BuildContext {
|
||||||
String? _getDefaultTranslation(String key, List arguments) {
|
String? _getDefaultTranslation(String key, List arguments) {
|
||||||
var locale = Localizations.localeOf(this);
|
var locale = Localizations.localeOf(this);
|
||||||
var code = locale.countryCode ?? 'nl';
|
var code = locale.countryCode ?? 'nl';
|
||||||
|
@ -86,8 +76,11 @@ extension AppShellTranslate on BuildContext {
|
||||||
return translationMap?[key]?.toString().format(arguments);
|
return translationMap?[key]?.toString().format(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
String translate(String key,
|
String translate(
|
||||||
{String? defaultValue, List<dynamic> arguments = const []}) {
|
String key, {
|
||||||
|
String? defaultValue,
|
||||||
|
List<dynamic> arguments = const [],
|
||||||
|
}) {
|
||||||
dynamic translateFunction = login().config.translate;
|
dynamic translateFunction = login().config.translate;
|
||||||
if (translateFunction == null) {
|
if (translateFunction == null) {
|
||||||
return _getDefaultTranslation(key, arguments) ?? defaultValue ?? key;
|
return _getDefaultTranslation(key, arguments) ?? defaultValue ?? key;
|
||||||
|
@ -100,21 +93,39 @@ extension AppShellTranslate on BuildContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginMain extends StatelessWidget {
|
class LoginMain extends StatefulWidget {
|
||||||
LoginMain({
|
const LoginMain({
|
||||||
required this.child,
|
required this.child,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
Widget _login(context) {
|
@override
|
||||||
return Builder(
|
State<LoginMain> createState() => _LoginMainState();
|
||||||
builder: (context) {
|
|
||||||
if (context.login().users.isLoggedIn(context)) {
|
|
||||||
return child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FlutterLogin.of(context)
|
class _LoginMainState extends State<LoginMain> {
|
||||||
|
bool _checkedIfLoggedIn = false;
|
||||||
|
bool _isLoggedIn = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (!_checkedIfLoggedIn) {
|
||||||
|
context.loginRepository().reLogin(
|
||||||
|
onLoggedIn: () => setState(
|
||||||
|
() {
|
||||||
|
_isLoggedIn = true;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_checkedIfLoggedIn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _isLoggedIn
|
||||||
|
? widget.child
|
||||||
|
: Builder(
|
||||||
|
builder: (context) => FlutterLogin.of(context)
|
||||||
.config
|
.config
|
||||||
.loginOptions
|
.loginOptions
|
||||||
.loginMethod
|
.loginMethod
|
||||||
|
@ -125,28 +136,21 @@ class LoginMain extends StatelessWidget {
|
||||||
.loginMethod
|
.loginMethod
|
||||||
.contains(LoginMethod.LoginInteractiveWithPhoneNumber)
|
.contains(LoginMethod.LoginInteractiveWithPhoneNumber)
|
||||||
? ChooseLogin(
|
? ChooseLogin(
|
||||||
child: child,
|
child: widget.child,
|
||||||
)
|
)
|
||||||
: EmailPasswordLogin(
|
: EmailPasswordLogin(
|
||||||
onPressedForgotPassword: FlutterLogin.of(context)
|
onPressedForgotPassword: FlutterLogin.of(context)
|
||||||
.config
|
.config
|
||||||
.loginOptions
|
.loginOptions
|
||||||
.onPressForgotPassword,
|
.onPressForgotPassword,
|
||||||
child: child,
|
child: widget.child,
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
CustomNavigator build(BuildContext context) => CustomNavigator(
|
|
||||||
pageRoute: PageRoutes.materialPageRoute,
|
|
||||||
home: _login(context),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppShellException implements Exception {
|
class LoginException implements Exception {
|
||||||
AppShellException(
|
LoginException(
|
||||||
this.error, [
|
this.error, [
|
||||||
this.stackTrace = StackTrace.empty,
|
this.stackTrace = StackTrace.empty,
|
||||||
]);
|
]);
|
||||||
|
@ -158,7 +162,7 @@ class AppShellException implements Exception {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Unhandled error occurred in Appshell: $error\n'
|
return 'Unhandled error occurred in login: $error\n'
|
||||||
'$stackTrace';
|
'$stackTrace';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,7 +337,7 @@ class LoginConfig extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
||||||
FlutterLogin? appShell;
|
FlutterLogin? login;
|
||||||
late final ConfigData configData;
|
late final ConfigData configData;
|
||||||
late LoginRepository repository;
|
late LoginRepository repository;
|
||||||
|
|
||||||
|
@ -352,7 +352,6 @@ class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
||||||
|
|
||||||
if (widget.repository != null) {
|
if (widget.repository != null) {
|
||||||
repository = widget.repository!;
|
repository = widget.repository!;
|
||||||
repository.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
@ -383,7 +382,7 @@ class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
||||||
!configData.loginOptions.socialOptions.forceAppleSignin))) {
|
!configData.loginOptions.socialOptions.forceAppleSignin))) {
|
||||||
// check if apple login is removed by developer
|
// check if apple login is removed by developer
|
||||||
if (configData.loginOptions.socialOptions.socialLogins.isEmpty) {
|
if (configData.loginOptions.socialOptions.socialLogins.isEmpty) {
|
||||||
throw AppShellException(
|
throw LoginException(
|
||||||
'If you enable LoginMethod.LoginInteractiveWithSocial you must provide atleast 1 social login option!');
|
'If you enable LoginMethod.LoginInteractiveWithSocial you must provide atleast 1 social login option!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,7 +390,7 @@ class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
appShell = FlutterLogin(
|
login = FlutterLogin(
|
||||||
config: widget.config ?? ConfigData.example(),
|
config: widget.config ?? ConfigData.example(),
|
||||||
repository: repository,
|
repository: repository,
|
||||||
app: widget.child,
|
app: widget.child,
|
||||||
|
@ -406,21 +405,10 @@ class LoginConfigState extends State<LoginConfig> with WidgetsBindingObserver {
|
||||||
if (isFlutterDefaultTheme(context)) {
|
if (isFlutterDefaultTheme(context)) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: defaultTheme,
|
data: defaultTheme,
|
||||||
child: appShell!,
|
child: login!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return appShell!;
|
return login!;
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
repository.dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppshellNoDisplayError {
|
|
||||||
AppshellNoDisplayError(this.error);
|
|
||||||
Object error;
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,8 @@ class ChooseLogin extends Login {
|
||||||
static String? finalEmail;
|
static String? finalEmail;
|
||||||
static String? finalPassword;
|
static String? finalPassword;
|
||||||
|
|
||||||
createState() => ChooseLoginState();
|
@override
|
||||||
|
ChooseLoginState createState() => ChooseLoginState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChooseLoginState extends LoginState<ChooseLogin> {
|
class ChooseLoginState extends LoginState<ChooseLogin> {
|
||||||
|
|
|
@ -47,11 +47,7 @@ class ForgotPasswordState extends State<ForgotPassword> {
|
||||||
context.translate('forgot_password.text.title'),
|
context.translate('forgot_password.text.title'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: context.login().screens.getAppshellScreenWrapper(
|
body: Column(
|
||||||
context,
|
|
||||||
backgroundImg:
|
|
||||||
context.login().config.loginOptions.backgroundImage,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
|
@ -62,12 +58,7 @@ class ForgotPasswordState extends State<ForgotPassword> {
|
||||||
top: 27,
|
top: 27,
|
||||||
left: 5,
|
left: 5,
|
||||||
),
|
),
|
||||||
child: context
|
child: context.login().config.appTheme.buttons.backButton(
|
||||||
.login()
|
|
||||||
.config
|
|
||||||
.appTheme
|
|
||||||
.buttons
|
|
||||||
.backButton(
|
|
||||||
context: context,
|
context: context,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -111,10 +102,8 @@ class ForgotPasswordState extends State<ForgotPassword> {
|
||||||
context.translate(
|
context.translate(
|
||||||
'forgot_password.error.email_does_not_exist',
|
'forgot_password.error.email_does_not_exist',
|
||||||
),
|
),
|
||||||
style: Theme.of(context)
|
style:
|
||||||
.textTheme
|
Theme.of(context).textTheme.bodyText2!.copyWith(
|
||||||
.bodyText2!
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context).errorColor,
|
color: Theme.of(context).errorColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -131,12 +120,7 @@ class ForgotPasswordState extends State<ForgotPassword> {
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 30),
|
margin: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
padding: const EdgeInsets.only(bottom: 40.0),
|
padding: const EdgeInsets.only(bottom: 40.0),
|
||||||
child: context
|
child: context.login().config.appTheme.buttons.primaryButton(
|
||||||
.login()
|
|
||||||
.config
|
|
||||||
.appTheme
|
|
||||||
.buttons
|
|
||||||
.primaryButton(
|
|
||||||
context: context,
|
context: context,
|
||||||
child: Text(
|
child: Text(
|
||||||
context.translate('forgot_password.button.submit'),
|
context.translate('forgot_password.button.submit'),
|
||||||
|
@ -180,7 +164,6 @@ class ForgotPasswordState extends State<ForgotPassword> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,30 +15,16 @@ class LoginAwaitEmailScreen extends StatefulWidget {
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_LoginAwaitEmailScreenState createState() => _LoginAwaitEmailScreenState();
|
LoginAwaitEmailScreenState createState() => LoginAwaitEmailScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LoginAwaitEmailScreenState extends State<LoginAwaitEmailScreen>
|
class LoginAwaitEmailScreenState extends State<LoginAwaitEmailScreen>
|
||||||
with NavigateWidgetMixin {
|
with NavigateWidgetMixin {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
context.loginRepository().addListener(registrateOrMainScreen);
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> registrateOrMainScreen() async {
|
|
||||||
var data =
|
|
||||||
await (context.loginRepository().userprofileExists() as FutureOr<bool>);
|
|
||||||
if (context.login().config.registrationOptions.registrationMode ==
|
|
||||||
RegistrationMode.Disabled ||
|
|
||||||
data) {
|
|
||||||
context.loginRepository().setLoggedIn(EmailPasswordLogin.finalEmail!);
|
|
||||||
widget.loginComplete!();
|
|
||||||
} else {
|
|
||||||
debugPrint('Register');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void navigateToEmailPage(BuildContext context) {
|
void navigateToEmailPage(BuildContext context) {
|
||||||
navigateFadeTo(
|
navigateFadeTo(
|
||||||
context,
|
context,
|
||||||
|
|
|
@ -87,7 +87,7 @@ class EmailLoginState extends LoginState<EmailPasswordLogin> {
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
context.loginRepository().setLoggedIn(EmailPasswordLogin.finalEmail!);
|
context.loginRepository().loggedIn = true;
|
||||||
navigateFadeToReplace(
|
navigateFadeToReplace(
|
||||||
context,
|
context,
|
||||||
(context) => widget.child,
|
(context) => widget.child,
|
||||||
|
|
|
@ -14,7 +14,6 @@ class LoginImage extends StatelessWidget {
|
||||||
if (config.loginImage == '') {
|
if (config.loginImage == '') {
|
||||||
image = const AssetImage(
|
image = const AssetImage(
|
||||||
'assets/images/login.png',
|
'assets/images/login.png',
|
||||||
package: 'appshell',
|
|
||||||
);
|
);
|
||||||
} else if (split.length < 2) {
|
} else if (split.length < 2) {
|
||||||
image = AssetImage(config.loginImage);
|
image = AssetImage(config.loginImage);
|
||||||
|
|
|
@ -36,11 +36,7 @@ abstract class LoginState<L extends Login> extends State<L>
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Scaffold(
|
Widget build(BuildContext context) => Scaffold(
|
||||||
backgroundColor: Theme.of(context).backgroundColor,
|
backgroundColor: Theme.of(context).backgroundColor,
|
||||||
body: context.login().screens.getAppshellScreenWrapper(
|
body: SizedBox(
|
||||||
context,
|
|
||||||
backgroundImg:
|
|
||||||
context.login().config.loginOptions.backgroundImage,
|
|
||||||
child: SizedBox(
|
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
@ -72,7 +68,6 @@ abstract class LoginState<L extends Login> extends State<L>
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget buildLoginPage(BuildContext context);
|
Widget buildLoginPage(BuildContext context);
|
||||||
|
|
|
@ -5,10 +5,10 @@ class Resend extends StatefulWidget {
|
||||||
const Resend({super.key});
|
const Resend({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ConfirmationState createState() => _ConfirmationState();
|
ConfirmationState createState() => ConfirmationState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ConfirmationState extends State<Resend> {
|
class ConfirmationState extends State<Resend> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import '../flutter_login_view.dart';
|
|
||||||
|
|
||||||
class ScreenService {
|
|
||||||
late bool shouldShowIntroductionScreen;
|
|
||||||
late bool shouldShowPolicyPage;
|
|
||||||
|
|
||||||
Widget getAppshellScreenWrapper(
|
|
||||||
BuildContext context, {
|
|
||||||
required Widget child,
|
|
||||||
String? backgroundImg,
|
|
||||||
}) {
|
|
||||||
var bgImage =
|
|
||||||
backgroundImg ?? context.login().config.appOptions.backgroundImage;
|
|
||||||
if (bgImage.isNotEmpty) {
|
|
||||||
late AssetImage image;
|
|
||||||
var split = bgImage.split(';');
|
|
||||||
|
|
||||||
image = split.length < 2
|
|
||||||
? AssetImage(bgImage)
|
|
||||||
: AssetImage(
|
|
||||||
split.first,
|
|
||||||
package: split.last,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: MediaQuery.of(context).size.height,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: image,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import '../flutter_login_view.dart';
|
|
||||||
|
|
||||||
class UserService extends ChangeNotifier {
|
|
||||||
late Map<String, dynamic>? _currentProfile = {};
|
|
||||||
|
|
||||||
set profile(Map<String, dynamic> profile) {
|
|
||||||
_currentProfile = profile;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> checkAutoLogin(FlutterLogin login) async {
|
|
||||||
debugPrint('checking autologin');
|
|
||||||
if (login.config.loginOptions.loginMode != LoginMode.NoLogin) {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 100), () async {
|
|
||||||
if (login.config.loginOptions.loginMode == LoginMode.LoginAutomatic) {
|
|
||||||
if (login.config.loginOptions.loginEmail == null ||
|
|
||||||
login.config.loginOptions.loginEmail == '') {
|
|
||||||
throw Exception('No login account for automatic login provided!');
|
|
||||||
}
|
|
||||||
if (login.config.loginOptions.loginPassword == null ||
|
|
||||||
login.config.loginOptions.loginPassword == '') {
|
|
||||||
throw Exception(
|
|
||||||
'No login password for automatic login provided!',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await login.repository.login(login.config.loginOptions.loginEmail!,
|
|
||||||
login.config.loginOptions.loginPassword!);
|
|
||||||
} else if (login.config.loginOptions.loginMode ==
|
|
||||||
LoginMode.LoginAnonymous) {
|
|
||||||
await login.repository.signInAnonymous();
|
|
||||||
} else {
|
|
||||||
var prefs = await SharedPreferences.getInstance();
|
|
||||||
var autoLoginMode = login.config.loginOptions.autoLoginMode;
|
|
||||||
if ((autoLoginMode != AutoLoginMode.alwaysOff &&
|
|
||||||
(prefs.getBool('autoLogin') ?? false) == true) ||
|
|
||||||
autoLoginMode == AutoLoginMode.alwaysOn) {
|
|
||||||
await login.repository.reLogin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addProfileListener(
|
|
||||||
void Function(Map<String, dynamic>) onProfileChanged,
|
|
||||||
) {
|
|
||||||
addListener(() {
|
|
||||||
onProfileChanged.call(_currentProfile!);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLoggedIn(BuildContext context) =>
|
|
||||||
context.loginRepository().isLoggedIn();
|
|
||||||
|
|
||||||
Future<void> logout(BuildContext context) =>
|
|
||||||
SharedPreferences.getInstance().then(
|
|
||||||
(value) {
|
|
||||||
value
|
|
||||||
.setBool('autoLogin', false)
|
|
||||||
.then((value) => context.loginRepository().logout());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class UserProfile {
|
|
||||||
late Map<String, dynamic> rawFields;
|
|
||||||
String? photoUrl;
|
|
||||||
|
|
||||||
@mustCallSuper
|
|
||||||
void init(Map<String, dynamic> raw) {
|
|
||||||
rawFields = raw;
|
|
||||||
photoUrl = raw['photo'];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isProfileComplete({List<String> requiredFields = const []}) {
|
|
||||||
return !requiredFields.any((element) => rawFields[element] == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic getValue(String key) {
|
|
||||||
return rawFields[key];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,10 +24,10 @@ class CustomNavigator extends StatefulWidget {
|
||||||
final List<NavigatorObserver> navigatorObservers;
|
final List<NavigatorObserver> navigatorObservers;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_CustomNavigatorState createState() => _CustomNavigatorState();
|
CustomNavigatorState createState() => CustomNavigatorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CustomNavigatorState extends State<CustomNavigator>
|
class CustomNavigatorState extends State<CustomNavigator>
|
||||||
implements WidgetsBindingObserver {
|
implements WidgetsBindingObserver {
|
||||||
GlobalKey<NavigatorState>? _navigator;
|
GlobalKey<NavigatorState>? _navigator;
|
||||||
|
|
||||||
|
@ -134,9 +134,11 @@ class _CustomNavigatorState extends State<CustomNavigator>
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
didChangeAppLifecycleState(AppLifecycleState state) {}
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {}
|
||||||
|
|
||||||
noSuchMethod(Invocation invocation) {
|
@override
|
||||||
|
void noSuchMethod(Invocation invocation) {
|
||||||
var name = invocation.memberName.toString();
|
var name = invocation.memberName.toString();
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'Expected a method to be called with name $name, '
|
'Expected a method to be called with name $name, '
|
||||||
|
@ -147,9 +149,9 @@ class _CustomNavigatorState extends State<CustomNavigator>
|
||||||
|
|
||||||
class PageRoutes {
|
class PageRoutes {
|
||||||
static final materialPageRoute =
|
static final materialPageRoute =
|
||||||
(<T>(RouteSettings settings, WidgetBuilder builder) =>
|
<T>(RouteSettings settings, WidgetBuilder builder) =>
|
||||||
MaterialPageRoute<T>(settings: settings, builder: builder));
|
MaterialPageRoute<T>(settings: settings, builder: builder);
|
||||||
static final cupertinoPageRoute =
|
static final cupertinoPageRoute =
|
||||||
(<T>(RouteSettings settings, WidgetBuilder builder) =>
|
<T>(RouteSettings settings, WidgetBuilder builder) =>
|
||||||
CupertinoPageRoute<T>(settings: settings, builder: builder));
|
CupertinoPageRoute<T>(settings: settings, builder: builder);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue