Refactor
This commit is contained in:
parent
66cdde323d
commit
89cf484f67
|
|
@ -53,7 +53,7 @@ class PersistenceRepository {
|
|||
|
||||
|
||||
Future<FileSystemEntity> delete() async {
|
||||
return await fileStorage.delete();
|
||||
return await fileStorage.exisits().then((exists) => exists ? fileStorage.delete() : null);
|
||||
}
|
||||
|
||||
Future<bool> exists() async {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:invoiceninja/redux/app/app_middleware.dart';
|
|||
import 'package:invoiceninja/redux/client/client_actions.dart';
|
||||
import 'package:invoiceninja/redux/client/client_middleware.dart';
|
||||
import 'package:invoiceninja/redux/invoice/invoice_actions.dart';
|
||||
import 'package:invoiceninja/ui/auth/init_screen.dart';
|
||||
import 'package:invoiceninja/ui/client/client_screen.dart';
|
||||
import 'package:invoiceninja/ui/client/edit/client_edit_vm.dart';
|
||||
import 'package:invoiceninja/ui/client/view/client_view_vm.dart';
|
||||
|
|
@ -88,10 +89,13 @@ class _InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
|||
|
||||
title: 'Invoice Ninja',
|
||||
routes: {
|
||||
LoginVM.route: (context) {
|
||||
InitScreen.route: (context) {
|
||||
widget.store.dispatch(LoadStateRequest(context));
|
||||
//widget.store.dispatch(LoadUserLogin());
|
||||
return LoginVM();
|
||||
return InitScreen();
|
||||
},
|
||||
LoginScreen.route: (context) {
|
||||
return LoginScreen();
|
||||
},
|
||||
DashboardScreen.route: (context) {
|
||||
widget.store.dispatch(LoadDashboardAction());
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ Middleware<AppState> _createLoadState(
|
|||
..companyState4.replace(company4State)
|
||||
..companyState5.replace(company5State));
|
||||
store.dispatch(LoadStateSuccess(appState));
|
||||
if (uiState.currentRoute != LoginVM.route &&
|
||||
if (uiState.currentRoute != LoginScreen.route &&
|
||||
authState.url.isNotEmpty) {
|
||||
NavigatorState navigator = Navigator.of(action.context);
|
||||
bool isFirst = true;
|
||||
|
|
@ -153,18 +153,18 @@ Middleware<AppState> _createLoadState(
|
|||
isFirst = false;
|
||||
});
|
||||
}
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
} else {
|
||||
store.dispatch(UserLogout());
|
||||
store.dispatch(LoadUserLogin());
|
||||
store.dispatch(LoadUserLogin(action.context));
|
||||
}
|
||||
}).catchError((error) => _handleError(store, error));
|
||||
}).catchError((error) => _handleError(store, error, action.context));
|
||||
|
||||
next(action);
|
||||
};
|
||||
|
|
@ -201,10 +201,10 @@ List<String> _getRoutes(AppState state) {
|
|||
return routes;
|
||||
}
|
||||
|
||||
_handleError(store, error) {
|
||||
_handleError(store, error, context) {
|
||||
print(error);
|
||||
store.dispatch(UserLogout());
|
||||
store.dispatch(LoadUserLogin());
|
||||
store.dispatch(LoadUserLogin(context));
|
||||
}
|
||||
|
||||
Middleware<AppState> _createUserLoggedIn(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'package:invoiceninja/redux/company/company_reducer.dart';
|
|||
// We create the State reducer by combining many smaller reducers into one!
|
||||
AppState appReducer(AppState state, action) {
|
||||
if (action is UserLogout) {
|
||||
return AppState();
|
||||
return AppState().rebuild((b) => b.authState.replace(state.authState));
|
||||
} else if (action is LoadStateSuccess) {
|
||||
return action.state.rebuild((b) => b.isLoading = false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ class LoadStateSuccess {
|
|||
LoadStateSuccess(this.state);
|
||||
}
|
||||
|
||||
class LoadUserLogin {}
|
||||
class LoadUserLogin {
|
||||
final BuildContext context;
|
||||
LoadUserLogin(this.context);
|
||||
}
|
||||
|
||||
class UserLoginLoaded {
|
||||
final String email;
|
||||
|
|
@ -41,5 +44,5 @@ class UserLoginFailure implements StopLoading {
|
|||
UserLoginFailure(this.error);
|
||||
}
|
||||
|
||||
class UserLogout {}
|
||||
class UserLogout implements PersistData {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja/ui/auth/login_vm.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:invoiceninja/redux/auth/auth_actions.dart';
|
||||
import 'package:invoiceninja/redux/app/app_state.dart';
|
||||
|
|
@ -39,6 +41,7 @@ _loadAuthLocal(Store<AppState> store, action) async {
|
|||
String secret = prefs.getString('secret');
|
||||
|
||||
store.dispatch(UserLoginLoaded(email, password, url, secret));
|
||||
Navigator.of(action.context).pushReplacementNamed(LoginScreen.route);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
|
|||
factory UIState() {
|
||||
return _$UIState._(
|
||||
selectedCompanyIndex: 0,
|
||||
currentRoute: LoginVM.route,
|
||||
currentRoute: LoginScreen.route,
|
||||
productUIState: ProductUIState(),
|
||||
clientUIState: ClientUIState(),
|
||||
invoiceUIState: InvoiceUIState(),
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class AppDrawerVM {
|
|||
while(Navigator.of(context).canPop()) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
Navigator.of(context).pushReplacementNamed(LoginVM.route);
|
||||
Navigator.of(context).pushReplacementNamed(LoginScreen.route);
|
||||
store.dispatch(UserLogout());
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class InitScreen extends StatelessWidget {
|
||||
|
||||
static final String route = '/';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(),
|
||||
),
|
||||
SizedBox(
|
||||
height: 4.0,
|
||||
child: LinearProgressIndicator(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,13 +6,14 @@ import 'package:invoiceninja/ui/app/form_card.dart';
|
|||
|
||||
import 'package:invoiceninja/utils/keys.dart';
|
||||
|
||||
class Login extends StatelessWidget {
|
||||
|
||||
class LoginView extends StatefulWidget {
|
||||
final bool isLoading;
|
||||
final bool isDirty;
|
||||
final AuthState authState;
|
||||
final Function(BuildContext, String, String, String, String) onLoginPressed;
|
||||
|
||||
Login({
|
||||
LoginView({
|
||||
Key key,
|
||||
@required this.isDirty,
|
||||
@required this.isLoading,
|
||||
|
|
@ -20,23 +21,47 @@ class Login extends StatelessWidget {
|
|||
@required this.onLoginPressed,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LoginState createState() => new _LoginState();
|
||||
}
|
||||
|
||||
class _LoginState extends State<LoginView> {
|
||||
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
// add controllers
|
||||
final _emailController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
final _urlController = TextEditingController();
|
||||
final _secretController = TextEditingController();
|
||||
|
||||
// keys
|
||||
static final ValueKey _emailKey = new Key(LoginKeys.emailKeyString);
|
||||
static final ValueKey _passwordKey = new Key(LoginKeys.passwordKeyString);
|
||||
static final ValueKey _urlKey = new Key(LoginKeys.urlKeyString);
|
||||
static final ValueKey _secretKey = new Key(LoginKeys.secretKeyString);
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
_emailController.text = widget.authState.email;
|
||||
_passwordController.text = widget.authState.password;
|
||||
_urlController.text = widget.authState.url;
|
||||
_secretController.text = widget.authState.secret;
|
||||
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
_urlController.dispose();
|
||||
_secretController.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!authState.isInitialized) {
|
||||
if (!widget.authState.isInitialized) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
|
|
@ -98,13 +123,13 @@ class Login extends StatelessWidget {
|
|||
*/
|
||||
obscureText: true,
|
||||
),
|
||||
authState.error == null
|
||||
widget.authState.error == null
|
||||
? Container()
|
||||
: Container(
|
||||
padding: EdgeInsets.only(top: 26.0, bottom: 4.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
authState.error,
|
||||
widget.authState.error,
|
||||
style: TextStyle(
|
||||
color: Colors.red,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -116,14 +141,14 @@ class Login extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
ProgressButton(
|
||||
label: 'LOGIN',
|
||||
isLoading: this.isLoading,
|
||||
isDirty: this.isDirty,
|
||||
label: AppLocalization.of(context).login.toUpperCase(),
|
||||
isLoading: widget.isLoading,
|
||||
isDirty: widget.isDirty,
|
||||
onPressed: () {
|
||||
if (!_formKey.currentState.validate()) {
|
||||
return;
|
||||
}
|
||||
this.onLoginPressed(
|
||||
widget.onLoginPressed(
|
||||
context,
|
||||
_emailController.text,
|
||||
_passwordController.text,
|
||||
|
|
|
|||
|
|
@ -11,18 +11,18 @@ import 'package:invoiceninja/redux/auth/auth_actions.dart';
|
|||
import 'package:invoiceninja/ui/auth/login.dart';
|
||||
import 'package:invoiceninja/redux/auth/auth_state.dart';
|
||||
|
||||
class LoginVM extends StatelessWidget {
|
||||
LoginVM({Key key}) : super(key: key);
|
||||
class LoginScreen extends StatelessWidget {
|
||||
LoginScreen({Key key}) : super(key: key);
|
||||
|
||||
static final String route = '/';
|
||||
static final String route = '/login';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: StoreConnector<AppState, _ViewModel>(
|
||||
converter: _ViewModel.fromStore,
|
||||
body: StoreConnector<AppState, LoginVM>(
|
||||
converter: LoginVM.fromStore,
|
||||
builder: (context, vm) {
|
||||
return Login(
|
||||
return LoginView(
|
||||
isLoading: vm.isLoading,
|
||||
isDirty: vm.isDirty,
|
||||
authState: vm.authState,
|
||||
|
|
@ -34,21 +34,21 @@ class LoginVM extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class _ViewModel {
|
||||
class LoginVM {
|
||||
bool isLoading;
|
||||
bool isDirty;
|
||||
AuthState authState;
|
||||
final Function(BuildContext, String, String, String, String) onLoginPressed;
|
||||
|
||||
_ViewModel({
|
||||
LoginVM({
|
||||
@required this.isLoading,
|
||||
@required this.isDirty,
|
||||
@required this.authState,
|
||||
@required this.onLoginPressed,
|
||||
});
|
||||
|
||||
static _ViewModel fromStore(Store<AppState> store) {
|
||||
return _ViewModel(
|
||||
static LoginVM fromStore(Store<AppState> store) {
|
||||
return LoginVM(
|
||||
isDirty: !store.state.authState.isAuthenticated,
|
||||
isLoading: store.state.isLoading,
|
||||
authState: store.state.authState,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class AppLocalization {
|
|||
'secret': 'Secret',
|
||||
'name': 'Name',
|
||||
'log_out': 'Log Out',
|
||||
'login': 'Login',
|
||||
'filter': 'Filter',
|
||||
'sort': 'Sort',
|
||||
'search': 'Search',
|
||||
|
|
@ -169,6 +170,7 @@ class AppLocalization {
|
|||
String get secret => _localizedValues[locale.languageCode]['secret'];
|
||||
String get name => _localizedValues[locale.languageCode]['name'];
|
||||
String get logOut => _localizedValues[locale.languageCode]['log_out'];
|
||||
String get login => _localizedValues[locale.languageCode]['login'];
|
||||
String get filter => _localizedValues[locale.languageCode]['filter'];
|
||||
String get sort => _localizedValues[locale.languageCode]['sort'];
|
||||
String get search => _localizedValues[locale.languageCode]['search'];
|
||||
|
|
|
|||
Loading…
Reference in New Issue