architecture 0.0.9 architecture: ^0.0.9 copied to clipboard
An Architectural solution for Flutter
Architectural solution for Flutter apps Inspired from Bloc pattern
Features #
More flexibility than Bloc pattern Simple to use Easy to test Easy to maintain
Getting started #
in order to use this package fully you need to install the following packages:
sealed_class_annotations sealed_class_generator
Usage #
create your model class like following:
import 'package:sealed_class_annotations/sealed_class_annotations.dart';
part 'signin_ui_state.sealed.dart';
@Sealed()
abstract class _SignInUIState {
void showContent(
bool isSignIn,
bool isLoading,
String? errorMessage,
);
}
@Sealed()
abstract class _SignInUIAction {
void showResetPasswordDialog();
}
then create your delegate class like following:
class SignInUiDelegate extends UIDelegate<SignInUIState, SignInUIAction> {
bool _isSignIn = true;
bool _isLoading = false;
SignInUiDelegate(this.authenticationApiHandler);
void init() {
_updateTheUi();
}
void tabSwitched(int index) {
_isSignIn = index == 0;
_updateTheUi();
}
void _updateTheUi({String? errorMessage}) {
add(
SignInUIState.showContent(
isSignIn: _isSignIn,
isLoading: _isLoading,
errorMessage: errorMessage,
),
);
}
void resetPasswordPressed() {
addAction(const SignInUIAction.showResetPasswordDialog());
}
Future<String> resetPassword(String email) {
return authenticationApiHandler.resetEmail(email);
}
void signInSignupButtonPressed({
required String email,
required String password,
}) {
_isLoading = true;
_updateTheUi();
if (_isSignIn) {
authenticationApiHandler
.signinViaEmail(
email: email,
password: password,
)
.then((value) {
_isLoading = false;
AppNavigation.openHome();
}).onError((error, stackTrace) {
debugPrint(error.toString());
_isLoading = false;
_updateTheUi(errorMessage: "login failed!");
});
} else {
authenticationApiHandler
.signupViaEmail(
email: email,
password: password,
)
.then((value) {
_isLoading = false;
AppNavigation.openHome();
}).onError((error, stackTrace) {
debugPrint(error.toString());
_isLoading = false;
_updateTheUi(errorMessage: "signup failed!");
});
}
}
}
And in your UI class you can use it like following:
@override
void initState() {
super.initState();
widget.delegate.init();
widget.delegate.uiActions().listen((event) {
event.when(
showResetPasswordDialog: () => // show reset password dialog widget,
);
});
}
@override
void dispose() {
_controller.dispose();
widget.delegate.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.delegate.getBuilder(
builder: (uiState) => uiState.when(
showContent: (isSignIn, isLoading, errorMessage) =>
_buildContent(
isSignIn,
isLoading,
errorMessage,
).padding(horizontal: 16, vertical: 16),
),
)
}