invoice/lib/ui/settings/user_details_vm.dart

249 lines
9.1 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
import 'package:invoiceninja_flutter/ui/settings/user_details.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/dialogs.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/oauth.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class UserDetailsScreen extends StatelessWidget {
const UserDetailsScreen({Key key}) : super(key: key);
static const String route = '/$kSettings/$kSettingsUserDetails';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, UserDetailsVM>(
converter: UserDetailsVM.fromStore,
builder: (context, viewModel) {
return UserDetails(
key: ValueKey(viewModel.state.settingsUIState.updatedAt),
viewModel: viewModel);
},
);
}
}
class UserDetailsVM {
UserDetailsVM({
@required this.user,
@required this.state,
@required this.onChanged,
@required this.onSavePressed,
@required this.onConnectGooglePressed,
@required this.onDisconnectGooglePressed,
@required this.onConnectGmailPressed,
@required this.onDisconnectGmailPressed,
@required this.onDisableTwoFactorPressed,
});
static UserDetailsVM fromStore(Store<AppState> store) {
final state = store.state;
return UserDetailsVM(
state: state,
user: state.uiState.settingsUIState.user,
onChanged: (user) => store.dispatch(UpdateUserSettings(user: user)),
onConnectGmailPressed: (context, completer, password) async {
print('## onConnectGmailPressed: 1');
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).connectedGmail);
try {
print('## onConnectGmailPressed: 2');
final signedIn = await GoogleOAuth.grantOfflineAccess(
(idToken, accessToken, serverAuthCode) {
print(
'## onConnectGmailPressed: 3 $idToken, $accessToken, $serverAuthCode');
if (idToken.isEmpty ||
accessToken.isEmpty ||
serverAuthCode.isEmpty) {
print('## onConnectGmailPressed: 4');
completer.completeError(
AppLocalization.of(context).anErrorOccurredTryAgain);
} else {
print('## onConnectGmailPressed: 4');
store.dispatch(ConnecGmailUserRequest(
serverAuthCode: serverAuthCode,
idToken: idToken,
completer: completer,
password: password,
));
}
});
if (!signedIn) {
print('## onConnectGmailPressed: 5');
completer.completeError(
AppLocalization.of(context).anErrorOccurredTryAgain);
}
} catch (error) {
print('## onConnectGmailPressed: 6');
completer.completeError(error);
}
print('## onConnectGmailPressed: 7');
},
onDisconnectGmailPressed: (context) {
confirmCallback(
context: context,
callback: () {
passwordCallback(
context: context,
callback: (password, idToken) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).disconnectedGmail);
store.dispatch(
SaveAuthUserRequest(
user: state.user.rebuild((b) => b..oauthUserToken = ''),
password: password,
idToken: idToken,
completer: completer,
),
);
});
});
},
onDisableTwoFactorPressed: (context) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).disabledTwoFactor);
confirmCallback(
context: context,
callback: () {
passwordCallback(
context: context,
callback: (password, idToken) {
store.dispatch(
SaveAuthUserRequest(
user: state.user
.rebuild((b) => b..isTwoFactorEnabled = false),
password: password,
idToken: idToken,
completer: completer,
),
);
});
});
},
onDisconnectGooglePressed: (context) {
if (!state.user.hasPassword) {
showErrorDialog(
context: context,
message: AppLocalization.of(context).pleaseFirstSetAPassword);
return;
}
confirmCallback(
context: context,
callback: () {
passwordCallback(
context: context,
callback: (password, idToken) {
final completer = snackBarCompleter<Null>(context,
AppLocalization.of(context).disconnectedGoogle);
completer.future.then((value) {
GoogleOAuth.disconnect();
});
store.dispatch(
SaveAuthUserRequest(
user: state.user.rebuild((b) => b..oauthProvider = ''),
password: password,
idToken: idToken,
completer: completer,
),
);
});
});
},
onConnectGooglePressed: (context) {
final completer = snackBarCompleter<Null>(
context, AppLocalization.of(context).connectedGoogle);
passwordCallback(
context: context,
callback: (password, idToken) async {
try {
final signedIn =
await GoogleOAuth.signUp((idToken, accessToken) {
if (idToken.isEmpty || accessToken.isEmpty) {
GoogleOAuth.signOut();
showErrorDialog(
context: context,
message: AppLocalization.of(context)
.anErrorOccurredTryAgain);
} else {
store.dispatch(
ConnecOAuthUserRequest(
provider: UserEntity.OAUTH_PROVIDER_GOOGLE,
password: password,
idToken: idToken,
completer: completer,
),
);
}
});
if (!signedIn) {
showErrorDialog(
context: context,
message:
AppLocalization.of(context).anErrorOccurredTryAgain);
}
} catch (error) {
showErrorDialog(context: context, message: error);
}
});
},
onSavePressed: (context) {
Debouncer.runOnComplete(() {
final localization = AppLocalization.of(context);
final completer =
snackBarCompleter<Null>(context, localization.savedSettings);
final appBuilder = AppBuilder.of(context);
completer.future.then((_) {
appBuilder.rebuild();
});
confirmCallback(
context: context,
message: localization.changingPhoneDisablesTwoFactor,
skip: state.user.phone ==
state.uiState.settingsUIState.user.phone ||
!state.user.isTwoFactorEnabled,
callback: () {
passwordCallback(
context: context,
callback: (password, idToken) {
store.dispatch(
SaveAuthUserRequest(
completer: completer,
user: store.state.uiState.settingsUIState.user,
password: password,
idToken: idToken,
),
);
});
});
});
},
);
}
final AppState state;
final UserEntity user;
final Function(UserEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onConnectGooglePressed;
final Function(BuildContext) onDisconnectGooglePressed;
final Function(BuildContext, Completer, String) onConnectGmailPressed;
final Function(BuildContext) onDisconnectGmailPressed;
final Function(BuildContext) onDisableTwoFactorPressed;
}